我有一大堆的NSOperations
加入NSOperationQueue
。 操作队列的maxConcurrentOperationCount
设置为1,使得NSOperations
运行一个在另一个之后。
现在,在completionBlock
上NSOperation
我想取消所有未决NSOperations
通过调用cancelAllOperations
在NSOperationQueue
。
它是安全的这样做呢? 我可以肯定的是, start
后,才下一次操作的-方法称为completionBlock
前面的操作中得到了充分的执行? 还是做completionBlock
以前的操作和同时运行的当前操作的任务吗?
之所以我问:我使用AFNetworking执行一批的AFHTTPRequestOperations
并要执行只有当批次的所有先前的请求是成功的一个请求。
下面不再是我发现似乎是真实的。 我已经重新运行在iOS 8和iOS 9和操作完成块测试始终与下一个操作同时运行。 目前,我没有看到一个方法,使操作等待之前完成模块来完成。
我只是想这种情况在样本项目。 下面是结果:
如果NSOperationQueue
的maxConcurrentOperationCount
被设置为1,一个NSOperation
的completionBlock
和下NSOperation
在队列中同时运行。
但是,如果每个NSOperation
通过调用链接到其前面的操作addDependency:
操作的执行等待,直到前面的操作的completionBlock
已完成。
所以,如果你想取消在接下来的操作completionBlock
当前操作,并确保它被取消开始之前,你必须设置之间的依赖NSOperations
通过调用addDependency:
的NSOperation建立,而不是完成操作的结果只是基于作业的完成状态的依赖。
然而,大多数我遇到的情景是这样的,操作的执行不仅取决于一些其它操作的完成,还可以根据从已完成操作的结果。
最后我做类似下面的方法,但仍在探索中,如果有一个更好的方法:
1)操作-A运行
2)操作-A compeletes及其completionBlock运行
3)在运行a的完成块,检查来自运行a获得的结果。
- 如果结果是X,创建操作-B,并添加到队列中。
- 如果结果是Y,创建操作-C,并添加到队列中。
- 如果结果是错误,创建操作-d(通常驱使动作),并添加到队列
所以,这最终成为操作的序列,被动态添加到队列中,根据完成的操作的结果。
我想出了另一种看似更好的办法,以确保只有在一定条件下(基于先前完成操作的结果)得到满足,否则,该操作被取消的operaion执行。
其中一个重要的考虑是用于运行操作条件检查不应该操作的子类中进行编码,从而使操作的子类是在不同的场景和应用poratble。
解决方案: - 有子类中的条件块属性,并设置任何条件形式,其中的操作实例。 - 覆盖“的isReady”中的NSOperation子类的吸气剂,检查有没有条件,从而确定其是否准备好执行。 - 若[超级的isReady]是YES,这意味着相关的操作都完成后,然后评估的必要条件。 - 如果条件检查通过,返回YES。 否则,设置isCancelled为YES和的isReady返回YES
代码:在接口文件中有块属性:
typedef BOOL(^ConditionBlock)(void);
@property (copy) ConditionBlock conditionBlock;
在实施中,覆盖的isReady,并取消:
@implementation ConditionalOperation
- (BOOL)isReady {
if([super isReady]) {
if(self.conditionBlock) {
if(!self.conditionBlock()) {
[self setCancelled:YES];
}
return YES;
} else {
return YES;
}
} else {
return NO;
}
}