开发者

Safe way to access objects of an NSOperation from the Main Thread?

开发者 https://www.devze.com 2023-03-10 06:35 出处:网络
The NSOperation has a delegate in the Main Thread which gets called upon some events that happen while the NSOperation runs.

The NSOperation has a delegate in the Main Thread which gets called upon some events that happen while the NSOperation runs.

The Delegate then accesses the properties of the NSOperation to get detailed information.

I'm concerned about this edge case: What if the NSOperation gets released by the queue a nanosecond after it called the delegate? I fear suddenly all the objects could be gone due to -release in -dealloc of the NSOperation, and then I get an EXC_BAD_ACCESS on the Main Thread.

How do you prevent this? I thought about doing something like this inside the NSOperation which runs in the background:

[(NSObject*)self.delegate performSelectorOnMainThread:@selector(operationUpdatedStatus:) withObject:[[self retain] autorelease] waitUntilDone:NO];

But I think this is nonsense because the autorelease pool al开发者_运维百科so gets drained instantly since it is local to the NSOperation.

So to be sure, must I retain the NSOperation in the delegate method on the Main Thread like this?

- (void)operationUpdatedStatus:(NSOperation*)op {
    [op retain]; // now we're safe to use it

    NSMutableArray *errorMessages = op.errors;
    for (NSString *errorMessage in errorMessages) {
        // lots of code
    }

    [op release];
}

Or is it guaranteed that the NSOperation object does not get killed until the run loop of the Main Thread finishes?


According to the NSObject docs, performSelectorOnMainThread retains the selector target as well as the object passed via withObject; neither are released until the selector that is to be performed has finished. So your [[self retain] autorelease] there is redundant.


I am doing a very similar type of coding in NSOperation right now. I add the operation to a queue, but since I know the operation is going away soon, I pass any needed values back to the calling class via an object in the delegate. Most of the time, I use an NSDictionary to do this if it's more than 1 object. I've never had an issue with deallocated instances using this method.

0

精彩评论

暂无评论...
验证码 换一张
取 消