NSOperation没有被正确取消

时间:2011-08-10 14:42:55

标签: ios nsoperation nsoperationqueue

我正在使用NSOperation执行一些繁重的数据解析,然后返回主线程,其中的对象已准备好供我的应用程序使用。我通过将它们放在单个NSOperationQueue上来处理所有操作。我这样做是为了控制在任何时候发生了多少处理,因为每个操作暂时使用相当高的内存占用量。

所以,我有一个场景,我可以在屏幕上有几个视图控制器。每个视图控制器都将在加载时创建解析操作并将其添加到队列中。我通过设置maxConcurrentOperationCount允许2个并发处理操作。每个视图控制器都创建一个处理操作,将它放在单例队列上,并将操作保留为属性,因此它有一个句柄。

如果视图控制器需要响应用户启动的Delete操作,我在视图控制器的dealloc方法中使用NSOperation属性来取消操作:

-(void)dealloc{
    [self.currentOperation cancel];
    [super dealloc];
}

在我的NSOperation子类中,我检查了几个地方的isCancelled属性(大部分在长时间运行的重要块之前)isCancelled属性并尝试响应它:

if([self isCancelled]){
    // Perform cleanup
    return;
}

问题是isCancelled属性评估为false并且操作继续,最终调用Core Data以尝试检索已删除的数据。即使我在核心数据获取请求之前立即进行了isCancelled检查,我也会看到这种情况发生。

我有一个解决方法来防止应用程序崩溃,但我想我可能会错误地执行该实现。有没有其他方法可以在处理时保持操作的处理,所以我可以在需要时取消它?我的方法是不是保留了正确的操作手柄并阻止它被正确取消?

1 个答案:

答案 0 :(得分:2)

你不能在dealloc中做那样的逻辑。

首先,dealloc必须将super的dealloc称为最后一行。完成后,对象消失,所有后续消息传递行为都未定义(将崩溃)。

队列也很可能会保留操作,因此dealloc中的取消毫无意义,因为在队列释放之前无法调用dealloc(除非你的内存管理被搞砸了)。

您需要完全将取消/失效逻辑与内存管理分开。