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
布尔值设置为 NO
但 isFinished
布尔值是设置为 YES
,即使当时正在执行操作。
此外,如果我尝试使用 operations
属性 查看我的 NSOperationQueue
中排队的操作,数组为空。
如果我覆盖 cancel
属性 及其 NSOperation
子类的 setter 方法,它会按预期工作。
我还从系统请求了一个很长的 运行 后台任务,它工作得很好,所以问题不在于应用程序在操作可以取消之前变得不活动。
我错过了什么?为什么 isCancelled
getter 没有改变,为什么 NSOperationQueue
的 operations
数组 属性 是空的,尽管我添加了操作并且它们正在执行在询问数组时以及为什么在执行操作时将 isFinished
布尔值设置为 YES
?
感谢 @KenThomases 和 @lead_the_zeppelin(请参阅 OP 中的评论)我能够查明我的代码中的缺陷:
自从我创建自定义 NSOperation
子类以将数据导入 Core Data 模型后,我的缺陷是嵌入了执行从子类的 -main
方法调用的导入的代码在我用来管理导入执行的 ManagedObjectContext
的异步 performBlock
方法的块回调范围内。
所以发生的事情是 -main
中的代码在另一个线程中异步 运行ning,而不是我的操作实例,毫不奇怪,它报告它已完成执行。就我而言,为了解决这个问题,我将 performBlock:
更改为 performBlockAndWait:
。
结论:如果你遇到和我一样的问题,检查你的自定义NSOperation
子类中的代码运行ning是否-main
实例方法不 运行 异步。
我在 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
布尔值设置为 NO
但 isFinished
布尔值是设置为 YES
,即使当时正在执行操作。
此外,如果我尝试使用 operations
属性 查看我的 NSOperationQueue
中排队的操作,数组为空。
如果我覆盖 cancel
属性 及其 NSOperation
子类的 setter 方法,它会按预期工作。
我还从系统请求了一个很长的 运行 后台任务,它工作得很好,所以问题不在于应用程序在操作可以取消之前变得不活动。
我错过了什么?为什么 isCancelled
getter 没有改变,为什么 NSOperationQueue
的 operations
数组 属性 是空的,尽管我添加了操作并且它们正在执行在询问数组时以及为什么在执行操作时将 isFinished
布尔值设置为 YES
?
感谢 @KenThomases 和 @lead_the_zeppelin(请参阅 OP 中的评论)我能够查明我的代码中的缺陷:
自从我创建自定义 NSOperation
子类以将数据导入 Core Data 模型后,我的缺陷是嵌入了执行从子类的 -main
方法调用的导入的代码在我用来管理导入执行的 ManagedObjectContext
的异步 performBlock
方法的块回调范围内。
所以发生的事情是 -main
中的代码在另一个线程中异步 运行ning,而不是我的操作实例,毫不奇怪,它报告它已完成执行。就我而言,为了解决这个问题,我将 performBlock:
更改为 performBlockAndWait:
。
结论:如果你遇到和我一样的问题,检查你的自定义NSOperation
子类中的代码运行ning是否-main
实例方法不 运行 异步。