R – when is it safe to release an NSThread


Below is the runloop for my secondary NSThread* processThread

To close the thread I call

//cancel secondary thread
[processThread cancel]
//signal condition
[processCondition broadcast];

Is it then safe to then call:

[processCondition release];
[processThread release];

or do i need to be sure that the thread has finished?

Perhaps like this?

NSTimeInterval timeout = [NSDate timeIntervalSinceReferenceDate] + (1.0/15.0);

while ([processThread isExecuting] && [NSDate timeIntervalSinceReferenceDate] < timeout)
    [NSThread sleepForTimeInterval: 1.0/1000.0 ];

[processCondition release];
[processThread release];

detailed code and explanation:

- (void)processLoop
    NSAutoreleasePool * outerPool = [[NSAutoreleasePool alloc] init];
    [processCondition lock];

    //outer loop    
    //this loop runs until my application exits
    while (![[NSThread currentThread] isCancelled])    
        NSAutoreleasePool *middlePool = [[NSAutoreleasePool alloc];
            //inner loop
            //this loop runs typically for a few seconds
            while (processGo && ![[NSThread currentThread] isCancelled]) 
                NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc]; init];
                //within inner loop
                //this takes a fraction of a second
                [self doSomething];
                [innerPool release];
            [self tidyThingsUp];

            [processCondition wait];
        [middlePool release];
    [processCondition unlock];      
    [outerPool release];

the combination of:

  • an inner while loop
  • NSCondition *processCondition
  • toggling processGo between YES and NO

allows me to stop and start the inner while loop without cancelling the thread.

if (processGo == YES)

execution enters the inner while loop.

When the main thread sets

processGo = NO

execution leaves the inner while loop and tidys up
on the next pass of the outer loop, execution hits

[processCondition wait]

and waits

if the the main thread resets

processGo == YES

and calls

[processCondition wait]

execution re-enters the inner loop

Best Solution

Yes, it is safe to call release against an NSThread if you are done with it. In non-GC Objective C code the idiom is that once you are done accessing an object you may release it. If anything else needs that object, including the object itself it their job to have a retain against it. In general if an object cannot be safely disposed at arbitrary times it will retain itself while it is in an unsafe state, and release itself when it can be safely disposed of.

This is how things like NSThread and NSURLConnection work (NSURLConnection actually retains its delegate and does a lot of fancy stuff to cope with the retain loop that occurs.