NSOperation & NSOperationQueue 取消

NSOperation & NSOperationQueue Cancellation

我在 NSOperationQueue 实例中排队的一些自定义 NSOperation 实例遇到了一些奇怪的问题:

当我调用 [myOperation cancel][myOperationQueue cancelAllOperations] 时,cancel 布尔值的 isCancelled getter 对于我的自定义 NSOperation 子类保持不变实例。

我正在尝试在调用应用委托 applicationWillResignActive 方法时取消操作。

我对 NSOperation 子类的实现是这样的:

我有一个单例,它强烈引用了我的 NSOperation 子类和 NSOperationQueue 实例的实例。

在该单例的方法中,我执行以下操作:

myNSOperationQueueInstance = [[NSOperationQueue alloc] init];
myCustomOperation_1 = [MyCustomOperationClass alloc] customInit];
myCustomOperation_2 = [MyCustomOperationClass alloc] customInit];

[myNSOperationQueueInstance addOperations:@[myCustomOperation_1,myCustomOperation_2] waitUntilFinished:NO];

到目前为止,一切正常,自定义操作开始执行。

但是,当我从 applicationWillResignActive 调用我的单例的另一个方法以使用 [myCustomOperation cancel][myNSOperationQueueInstance cancelAllOperations] 取消我的自定义操作时,isCancelled 布尔值保持不变(我在我的自定义操作的执行循环中定期检查 isCancelled

另一个有趣的事情是,在应该取消操作的相同方法中,如果我用 NSLog 检查 isCancelled, isExecuting, isAsynchronous 布尔值设置为 NOisFinished 布尔值是设置为 YES,即使当时正在执行操作。

此外,如果我尝试使用 operations 属性 查看我的 NSOperationQueue 中排队的操作,数组为空。

如果我覆盖 cancel 属性 及其 NSOperation 子类的 setter 方法,它会按预期工作。

我还从系统请求了一个很长的 运行 后台任务,它工作得很好,所以问题不在于应用程序在操作可以取消之前变得不活动。

我错过了什么?为什么 isCancelled getter 没有改变,为什么 NSOperationQueueoperations 数组 属性 是空的,尽管我添加了操作并且它们正在执行在询问数组时以及为什么在执行操作时将 isFinished 布尔值设置为 YES

感谢 @KenThomases@lead_the_zeppelin(请参阅 OP 中的评论)我能够查明我的代码中的缺陷:

自从我创建自定义 NSOperation 子类以将数据导入 Core Data 模型后,我的缺陷是嵌入了执行从子类的 -main 方法调用的导入的代码在我用来管理导入执行的 ManagedObjectContext 的异步 performBlock 方法的块回调范围内。

所以发生的事情是 -main 中的代码在另一个线程中异步 运行ning,而不是我的操作实例,毫不奇怪,它报告它已完成执行。就我而言,为了解决这个问题,我将 performBlock: 更改为 performBlockAndWait:

结论:如果你遇到和我一样的问题,检查你的自定义NSOperation子类中的代码运行ning是否-main 实例方法不 运行 异步。