5

我有一堆NSOperations添加到NSOperationQueue. 操作队列已maxConcurrentOperationCount设置为 1,以便NSOperations一个接一个地运行。

现在,completionBlockNSOperationNSOperations通过调用来取消所有挂起cancelAllOperationsNSOperationQueue.

这样做安全吗?我可以确定只有在上一个操作的完全执行start之后才调用下一个操作的 -method吗?completionBlock还是completionBlock上一个操作的任务和当前操作的任务同时运行?

我问的原因:我使用 AFNetworking 执行一批,AFHTTPRequestOperations并且仅当该批的所有先前请求都成功时才想执行一个请求。

4

3 回答 3

5

我在下面的发现似乎不再正确。我在 iOS 8 和 iOS 9 上重新运行了测试,并且操作的完成块始终与下一个操作同时运行。目前,我没有看到让操作等待前一个完成块完成的方法。


我刚刚在示例项目中尝试了这种情况。结果如下:

如果NSOperationQueue's设置maxConcurrentOperationCount为 1,则队列中的an和下一个会同时运行。NSOperationcompletionBlockNSOperation

但是,如果 everyNSOperation通过调用 链接到其前一个操作addDependency:,则操作的执行将等待前一个操作completionBlock完成。

所以,如果你想取消completionBlock当前操作中的下一个操作,并确保它在它开始之前被取消,你必须NSOperations通过调用来设置它们之间的依赖关系addDependency:

于 2012-07-11T08:04:33.683 回答
1

NSOperation 仅基于操作的完成状态不是已完成操作的结果建立依赖关系。

但是,我遇到的大多数场景都是这样的,操作的执行不仅取决于其他一些操作的完成,还取决于从完成的操作中获得的结果。

我最终做了下面的方法,但仍在探索是否有更好的方法:

1) 操作-A 运行

2) 操作-A 完成并且它的完成块运行

3) 在 OperationA 的完成块中,检查从 Operation-A 获得的结果。

  • 如果结果为 X,则创建 Operation-B 并添加到队列中。
  • 如果结果为 Y,则创建 Operation-C 并添加到队列中。
  • 如果结果为错误,则创建 Operation-D(通常是警报操作)并添加到队列中

因此,这最终成为一系列操作,根据已完成操作的结果动态添加到队列中。

于 2018-07-04T06:44:06.523 回答
1

我想出了另一种看似更好的方法来确保仅在满足某些条件(基于先前完成的操作的结果)时才执行操作,否则操作被取消。

这里一个重要的考虑是运行操作的条件检查不应该在操作子类中编码,从而允许操作子类在不同的场景和应用程序中可移植。

解决方案: - 在子类中具有条件块属性,并设置实例化操作的任何条件形式。- 覆盖 NSOperation 子类的“isReady”getter,检查那里的条件,从而确定它是否准备好执行。- 如果[super isReady]为YES,表示依赖操作全部完成,则评估必要条件。- 如果条件检查通过,返回YES。否则,将 isCancelled 设置为 YES 并为 isReady 返回 YES

代码:在接口文件中有block属性:

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;
        }
    }
于 2018-07-04T17:33:14.177 回答