NSOperationQueue:NSOperation的序列,具有依赖性VS(maxConcurrentOperationCount == 1)? [英] NSOperationQueue: a sequence of NSOperation's with dependencies VS (maxConcurrentOperationCount == 1)?
问题描述
例如,我有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
,在这种情况下,我无法完全清除队列.
I could simply add all the operations in correct order. But for example if op2
is cancelled then I should also cancel op3
and I can't fully clear a queue in this case.
我的问题:
1)将这样的操作顺序与maxConcurrentOperationCount == 1
结合使用是否安全?
1)Is it safe to combine such sequences of operations with maxConcurrentOperationCount == 1
?
2)如果我在op1
和op2
之间交换,该程序将实际做什么? (op2
应该在op1
之后执行,但是队列只能同时从操作中获取一个)
2)What will the program actually do if I swap around op1
and op2
? (op2
should be performed after op1
but the queue is able to take only one from the operations simultaneously)
P.S.在我的应用程序中,我使用AFHTTPRequestOperation
.它的继承层次:
P.S. In my application I use AFHTTPRequestOperation
. Its inheritance hierarchy:
AFHTTPRequestOperation
-> AFURLConnectionOperation
-> NSOperation
所以我不能简单地采用NSOperation
的其他子类.
So I can't simply take other subclass of NSOperation
.
推荐答案
要回答您的问题:
- 将这个特定的操作序列与您使用
maxConcurrentOperations = 1
给出的依赖项结合起来是安全的. - 如果颠倒
op1
和op2
的依赖顺序,则队列将运行op2
,op3
和op1
或op2
,op1
,op3
.
- It's safe to combine this particular sequence of operations with the dependencies you have given with
maxConcurrentOperations = 1
. - The queue will run
op2
,op3
andop1
orop2
,op1
,op3
if you reverse the dependency order ofop1
andop2
.
在您指定的依赖链中没有任何棘手的问题,并且NSOperationQueue
可以自动处理.仅当您指定循环依赖项(例如op3
依赖于op1
),或者您的操作未添加到队列中,因此无法执行以满足依赖项时,您才真正遇到麻烦
Theres nothing tricky in the dependency chain you've specified and NSOperationQueue
can take care of things automatically. You can only really get into trouble if you specify a circular dependency (e.g op3
depends on op1
), or you have an operation that isn't added to the queue, and so can't get executed to satisfy a dependency.
Apple在 NSOperationQueue中说取消类参考:
取消操作会导致该操作忽略其可能具有的任何依赖关系.此行为使队列可以尽快执行操作的start方法.依次使用start方法将操作移至完成状态,以便可以将其从队列中删除.
Canceling an operation causes the operation to ignore any dependencies it may have. This behavior makes it possible for the queue to execute the operation’s start method as soon as possible. The start method, in turn, moves the operation to the finished state so that it can be removed from the queue.
所有NSOperation子类都应通过以下方法正确处理取消:首先检查其是否已取消,然后立即完成操作而不执行任何操作.如果不这样做,那就是一个错误,即使取消操作,操作也可能会执行.
All NSOperation subclasses should handle cancellation correctly by first checking to see if it has been cancelled and then immediately finish the operation without performing any actions. If this isn't done then it's a bug, and operations may execute even though they have been cancelled.
(有趣的是,这也适用于NSBlockOperation,我没有意识到.您需要在块中明确检查self.isCancelled
.)
(Interestingly this also applies for NSBlockOperation, which I didn't realise. You explicitly need to check self.isCancelled
in the block).
我在App Store上使用了 CodeRunner 来尝试此操作全力以赴,并略微修改了您的程序.复制如下.
I used CodeRunner on the App Store to try this all out and modified your program slightly. It's reproduced below.
#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
.
For a NSBlockOperation
to refer to itself you need to do this, which is a bit disgusting but looks better in a NSOperation
subclass as you can refer to self
.
__block NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op1 cancelled=%d", op1.cancelled); }];
这篇关于NSOperationQueue:NSOperation的序列,具有依赖性VS(maxConcurrentOperationCount == 1)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!