ios – NSOperation和NSOperationQueue取消

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

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

我试图在调用app委托applicationWillResignActive方法时取消操作.

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

>自定义init方法
>实施主要

我有一个单例,强烈引用我的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,布尔值被设置为NO,但isFinished布尔值设置为YESeven,尽管那时操作正在执行.

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

如果我覆盖取消属性及其NSOperation子类的setter方法,它按预期工作.

我还从系统请求了一个长时间运行的后台任务,该任务运行得很好所以问题不是应用程序在操作取消之前变为非活动状态.

我错过了什么?为什么isCancelled getter不会改变,为什么NSOperationQueue的操作数组属性为空,尽管事实上我添加了操作并且在查询数组时它们正在执行以及为什么在执行操作时isFinished布尔值设置为YES?

最佳答案 感谢@KenThomases和@lead_the_zeppelin(参见OP中的评论),我能够找到代码中的缺陷:

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

所以发生的事情是内部的代码 – 在另一个线程中异步运行而不是我的操作实例,这并不奇怪,它报告它已完成执行.在我的例子中,为了解决这个问题,我用performBlockAndWait改变了pe​​rformBlock:.

结论:如果您遇到过像我这样的问题,请检查在自定义NSOperation子类-main实例方法中运行的代码是否不是异步运行.

点赞