1

I have a pretty standard setup. I have a UIViewController to handle user interaction and a somewhat long running NSThread that does the actual work when the UI Controller shows up. One issue I've had is when I want to cancel the NSThread. Standard NSThread semantics is alright. I want the thread to finish, clean itself up (so that it releases the reference to my UIViewController) and then pop the UIViewController. So my code looks something like this:

In NSThread selector:

-(void) nsThreadWork
{
  // do work here
  @synchronized(self)
  {
    [nsThreadInstance release];
    nsThreadInstance = nil;
  }
}

In UIViewController that spawns the thread:

 -(void) startThread    
 {
   nsThreadInstance = [[NSThread alloc] initWithTarget:self 
                                        selector:@(nsThreadWork) ...];
   [nsThreadInstance start];
   [nsThreadInstance release];
 }

And if I want to cancel:

// assume that this will be retried until we can execute this successfully.
-(void) cancelBackgroundOpAndPopViewController
{
  @synchronized(self)
  {
    if (nsThreadInstance == nil)
    { 
        [self popViewController];
    }
  }
} 

I doubt if this is correct though. The problem is, UI elements can only be manipulated from the main thread. If I pop the view controller before NSThread exits, NSThread will exit and release the view controller which means it will be dealloced from NSThread's context which will cause an assert. Everything appears to work properly with the above code, but I dont understand when the runloop deallocates NSThread. Can anyone provide any insight?

EightyEight
  • 3,430
  • 4
  • 36
  • 67
  • 1
    What's retaining the thread? Alternatively stated: Why is the thread releasing itself? – Peter Hosey Aug 23 '10 at 16:14
  • Good question. Nobody's retaining the thread besides the runloop, and the fact that it's not released right after alloc. I'm using it to determine whether the thread is still alive.. But the eventual goal is of course to enforce the fact that thread is deallocated before the view controller. Maybe this whole things needs to be refactored... – EightyEight Aug 23 '10 at 16:40
  • Run loops don't retain threads, because run loops are per-thread. – Peter Hosey Aug 23 '10 at 20:19
  • Huh, makes sense. So, if nobody retains the thread, when I release it from the thread's run loop. Does it get released right away? Releasing the reference to the view controller? – EightyEight Aug 23 '10 at 23:40
  • 1
    You aren't releasing it from its run loop; you're releasing it from its main method. When you release the thread, it is released right away. The docs say only that the thread object releases its target when the thread finishes; it does not state the relevance or irrelevance of the thread object's lifetime. I would guess irrelevance: Releasing the thread object does not terminate the thread; the only way to exit the thread is to return from its function (method, in the case of NSThread). For cleanliness, if nothing else, I would not release the NSThread until after it exits. – Peter Hosey Aug 24 '10 at 05:35

0 Answers0