【发布时间】:2017-10-01 02:40:43
【问题描述】:
我正在开发一个框架,为了确保非阻塞公共方法,我使用NSOperationQueue 将所有公共方法调用放入操作队列并立即返回。
不同操作之间没有关系或依赖关系,唯一重要的是操作以 FIFO 顺序启动,与它们添加到队列中的顺序相同。
这是我当前实现的一个示例 (sample project here):
@implementation Executor
-(instancetype) init {
self = [super init];
if(self) {
_taskQueue = [[NSOperationQueue alloc] init];
_taskQueue.name = @"com.d360.tasks";
}
return self;
}
-(void) doTask:(NSString*) taskName
{
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"executing %@", taskName);
}];
[self.taskQueue addOperation:operation];
}
虽然我意识到操作开始的顺序不一定是它们被添加到队列中的顺序。例如,如果我调用
[self.executor doTask:@"Task 1"];
[self.executor doTask:@"Task 2"];
有时Task 2 在Task 1 之后启动。
问题是如何确保 FIFO 执行开始?
我可以使用_taskQueue.maxConcurrentOperationCount = 1; 来实现它,但这一次只允许进行一次我不想要的操作。一个操作不应阻塞任何其他操作,只要它们以正确的顺序启动,它们就可以同时运行。
我还研究了NSOperationQueuePriority 属性,如果我知道我不知道的调用的优先级,它将起作用。事实上,即使我将之前添加的操作发送到NSOperationQueuePriorityHigh,将第二个操作发送到NSOperationQueuePriorityNormal,也不能保证顺序。
[self.executor doTask:@"Task 1" withQueuePriority:NSOperationQueuePriorityHigh];
[self.executor doTask:@"Task 2" withQueuePriority:NSOperationQueuePriorityNormal];
输出有时是
executing Task 2
executing Task 1
有什么想法吗?
谢谢, 一月
【问题讨论】:
-
您说:“后进先出顺序与它们添加到队列中的顺序相同”。这个说法是矛盾的——你说的是后进先出顺序,但你描述的是先进先出顺序。那么它是什么?
-
是的,抱歉,它是 FIFO(更新)
-
您是说一个操作不应阻塞任何其他操作,只要它们以正确的顺序启动,它们就可以同时运行意思是任务是独立的。然后你想要
FIFO排序,最终添加dependency。老实说,FIFO这个概念本身就是一个条件操作。所以只要你的任务是独立的,为什么排序会让人头疼?? -
有一个执行顺序,not 与一个操作在它的依赖完成 imo 之前无法启动的依赖不同。但我明白你的意思,我应该重新考虑我的设计并在必要时添加依赖项
标签: objective-c nsoperation nsoperationqueue