NSOperation 在主线程中有一个委托,它会在 NSOperation 运行时发生的一些事件上被调用。
然后,委托访问 NSOperation 的属性以获取详细信息。
我担心这种边缘情况:如果 NSOperation 在调用委托后一纳秒被队列释放怎么办?我担心突然间所有对象可能会因为 NSOperation 的 -dealloc 中的 -release 而消失,然后我在主线程上得到 EXC_BAD_ACCESS 。
你如何防止这种情况发生?我想过在后台运行的 NSOperation 中做类似的事情:
[(NSObject*)self.delegate performSelectorOnMainThread:@selector(operationUpdatedStatus:) withObject:[[self retain] autorelease] waitUntilDone:NO];
但我认为这是无意义的,因为自动释放池也会立即耗尽,因为它是 NSOperation 的本地资源。
所以可以肯定的是,我必须像这样在主线程的委托方法中保留 NSOperation 吗?
- (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];
}
或者是否保证 NSOperation 对象在主线程的运行循环完成之前不会被杀死?
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 also 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?
发布评论
评论(2)
根据 NSObject 文档,
performSelectorOnMainThread
也保留选择器目标作为通过withObject
传递的对象;在要执行的选择器完成之前,两者都不会被释放。所以你的[[self keep] autorelease]
是多余的。According to the NSObject docs,
performSelectorOnMainThread
retains the selector target as well as the object passed viawithObject
; neither are released until the selector that is to be performed has finished. So your[[self retain] autorelease]
there is redundant.我现在正在 NSOperation 中进行非常类似的编码。我将该操作添加到队列中,但由于我知道该操作很快就会消失,因此我通过委托中的对象将任何所需的值传递回调用类。大多数时候,如果对象超过 1 个,我会使用 NSDictionary 来执行此操作。我从来没有遇到过使用此方法释放实例的问题。
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.