要回答您的问题:
- 将这个特定的操作序列与您给出的依赖项结合起来是安全的
maxConcurrentOperations = 1
。
- 如果反转 and 的依赖顺序,队列将运行
op2
,op3
和op1
or op2
, 。op1
op3
op1
op2
您指定的依赖链没有什么棘手的,NSOperationQueue
可以自动处理。op3
如果您指定循环依赖项(例如,取决于op1
),或者您有一个未添加到队列中的操作,因此您无法执行以满足依赖项,您只会真正遇到麻烦。
Apple对 NSOperationQueue 类参考中的取消有这样的说法:
取消操作会导致操作忽略它可能具有的任何依赖项。这种行为使队列可以尽快执行操作的 start 方法。反过来, start 方法将操作移动到完成状态,以便可以将其从队列中删除。
所有 NSOperation 子类都应该正确处理取消,首先检查它是否已被取消,然后立即完成操作而不执行任何操作。如果不这样做,那么这是一个错误,即使操作已被取消,操作也可能会执行。
(有趣的是,这也适用于 NSBlockOperation,我没有意识到。您明确需要签self.isCancelled
入块)。
我在 App Store 上使用CodeRunner尝试了这一切,并稍微修改了你的程序。转载如下。
#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];
}
}
要让 aNSBlockOperation
引用自己,您需要这样做,这有点恶心,但在NSOperation
子类中看起来更好,因为您可以引用self
.
__block NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op1 cancelled=%d", op1.cancelled); }];