是否有可能使用NSoperationQueue
其设置对象为串行FIFO队列maxConcurrentOperationCount
为1?
我注意到, 文档状态...
对于一个队列,其并发操作的最大数量设置为1,这相当于一个串行队列。 但是,你不应该依赖于操作对象的串行执行。
这是否意味着FIFO执行不保证?
是否有可能使用NSoperationQueue
其设置对象为串行FIFO队列maxConcurrentOperationCount
为1?
我注意到, 文档状态...
对于一个队列,其并发操作的最大数量设置为1,这相当于一个串行队列。 但是,你不应该依赖于操作对象的串行执行。
这是否意味着FIFO执行不保证?
在大多数情况下,这将是FIFO。 但是,您可以建立依赖性NSOperations之间,使得年初提交的操作将让其他运营方式传递的队列中,直到其依赖性得到满足。
这种依赖关系管理就是为什么文档表明,FIFO岬不能得到保证。 如果你不使用的依赖,但是,你应该罚款依靠它。
更新 :的NSOperation也有queuePriority
属性,它也可能导致操作在非FIFO的顺序执行。 没有未决的依赖关系的优先级最高的操作将始终首先执行。
一个子类的NSOperation也可能会覆盖-isReady
,这可能导致其移回队列中。
所以,在你的队列执行是保证连续 ,在不超过一个操作将在这个队列中的时间运行。 但是,苹果不能保证FIFO; 这取决于你和你把作业做什么。
如由文档中提到的队列没有FIFO。 你可以把它严格的FIFO,如果你确保任何新的操作取决于在队列最后添加的操作,它只能同时运行一个操作。 奥马尔的解决方案是正确的,但更普遍的,你可以做到以下几点:
NSOperationQueue* queue = [[ NSOperationQueue alloc ] init];
queue.maxConcurrentOperationCount = 1;
NSOperation* someOperation = [ NSBlockOperation blockOperationWithBlock:^(void) { NSLog(@"Done.");} ];
if ( queue.operations.count != 0 )
[ someOperation addDependency: queue.operations.lastObject ];
这工作,因为queue.operations是一个数组:无论你加不重新排序(它不是实例的NSSet)。 你也可以简单的类别添加到您的NSOperationQueue:
@interface NSOperationQueue (FIFOQueue)
- (void) addOperationAfterLast:(NSOperation *)op;
@end
@implementation NSOperationQueue (FIFOQueue)
- (void) addOperationAfterLast:(NSOperation *)op
{
if ( self.maxConcurrentOperationCount != 1)
self.maxConcurrentOperationCount = 1;
NSOperation* lastOp = self.operations.lastObject;
if ( lastOp != nil )
[ op addDependency: lastOp ];
[ self addOperation:op];
}
@end
并使用[队列addOperationAfterLast:myOperation]。 queuePriority无关与FIFO,它关系到作业调度。
编辑:按照下面的注释,暂停队列,如果检查的次数也不够。 我相信,这种形式很好(在测试时,这不会产生竞争条件,并不会崩溃)。
一些信息: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperationQueue_class/#//apple_ref/occ/instp/NSOperationQueue/suspended
要使用nsInvocationopration做一个简单的FIFO,您将需要设置一个操作上的其他应用addDependency将取决于:方法
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *oper1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSth:) object:@"1"];
NSInvocationOperation *oper2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSth:) object:@"2"];
NSInvocationOperation *oper3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSth:) object:@"3"];
[oper2 addDependency:oper1];
[oper3 addDependency:oper2];
//oper3 depends on oper2 wich depends on oper1
//order of execution will ber oper1->oper2->oper3
//Changing the oreder will not change the result
[queue addOperation:oper2];
[queue addOperation:oper3];
[queue addOperation:oper1];
- (void) doSth:(NSString*)str
{
NSLog(str); //log will be 1 2 3
//When you remove the addDependency calls, the logging result that i got where
//different between consecutive runs i got the following
//NSLog(str); //log will be 2 1 3
//NSLog(str); //log will be 3 1 2
}
注 :如果您使用NSInvocationOperation
然后设置maxConcurrentOperationCount
1将最有可能做的伎俩给你,因为的isReady不会被你编辑
但maxConcurrentOperationCount
= 1就不会是一个很好的解决方案,如果你是刨去创建自己的子类NSOperation
由于的NSOperation衍生工具,你可以重写isReady
功能和返回无,(想象一下一些操作,将需要从服务器的一些数据等待才能正常工作),在这些情况下,您将返回isReady no
,直到你真的准备好了在这些情况下,你将需要添加dependencies
之间operations
的队列中
从苹果公司的文档,这相当于一个串行队列。 但是,你不应该依赖于操作对象的串行执行。 在操作的准备就绪的变化可改变所得的执行顺序