NSOperationQueue:一系列具有依赖关系的NSOperation(maxConcurrentOperationCount == 1)?

时间:2014-11-06 21:29:22

标签: dependencies dependency-management nsoperation nsoperationqueue afhttprequestoperation

例如,我有3个对象:

NSOperation *op1 = ...;
NSOperation *op2 = ...;
NSOperation *op3 = ...;

[op3 addDependency:op2];
[op2 addDependency:op1];

NSOperationQueue *queue = ...;
queue.maxConcurrentOperationCount = 1;
[queue addOperations:@[op1, op2, op3] waitUntilFinished:NO];

我可以简单地按正确的顺序添加所有操作。但是,例如,如果取消op2,那么我也应取消op3,在这种情况下我无法完全清除队列。

我的问题:

1)将这些操作序列与maxConcurrentOperationCount == 1

结合起来是否安全

2)如果我调换op1op2,该计划实际会做什么? (op2应该在op1之后执行,但队列只能同时从操作中获取一个)

P.S。在我的应用程序中,我使用AFHTTPRequestOperation。它的继承层次结构:

AFHTTPRequestOperation - > AFURLConnectionOperation - > NSOperation

所以我不能简单地使用NSOperation的其他子类。

1 个答案:

答案 0 :(得分:1)

回答你的问题:

  1. 将此特定操作序列与您使用maxConcurrentOperations = 1提供的依赖关系结合起来是安全的。
  2. 如果您撤消{的依赖顺序,则队列将运行op2op3op1op2op1op3 {1}}和op1
  3. 在您指定的依赖关系链中没有任何棘手的问题,op2可以自动处理事情。如果指定循环依赖项(例如NSOperationQueue取决于op3),或者您的操作未添加到队列中,则无法执行,因此无法执行满足依赖。

    Apple在the NSOperationQueue class reference中有关于取消的说法:

      

    取消操作会导致操作忽略它可能具有的任何依赖关系。此行为使队列可以尽快执行操作的start方法。反过来,start方法将操作移动到完成状态,以便可以从队列中删除它。

    所有NSOperation子类都应该通过首先检查它是否已被取消然后立即完成操作而不执行任何操作来正确处理取消。如果没有这样做,那么它就是一个错误,即使它们被取消也可以执行操作。

    (有趣的是,这也适用于NSBlockOperation,我没有意识到。你明确需要检查块中的op1

    我在App Store上使用了CodeRunner来尝试这一切并稍微修改了你的程序。它转载如下。

    self.isCancelled

    要让#import <Foundation/Foundation.h> int main(int argc, char *argv[]) { @autoreleasepool { NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op1"); }]; NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op2"); }]; NSOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op3"); }]; [op3 addDependency:op2]; [op2 addDependency:op1]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; queue.maxConcurrentOperationCount = 1; [queue addOperations:@[op1, op2, op3] waitUntilFinished:YES]; } } 引用自己,你需要这样做,这有点令人作呕,但在NSBlockOperation子类中看起来更好,因为你可以参考NSOperation

    self