我有许多需要串行执行的任务,但任务包括完成块中的下一个块。
什么是一次完成这些任务的好技术,在当前任务完成其完成块后开始下一个任务?
除了具有串行 NSOperationQueue 的 NSOperation 子类之外,还有其他技术吗?
标准解决方案:
NSOperationQueue
与. maxConcurrentOperationCount
_ 1
你说你不想那样做,但你没有说为什么。串行队列是最合乎逻辑的解决方案。
例如:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
NSLog(@"Starting #1");
sleep(3);
NSLog(@"Finishing #1");
}];
[queue addOperationWithBlock:^{
NSLog(@"Starting #2");
sleep(3);
NSLog(@"Finishing #2");
}];
[queue addOperationWithBlock:^{
NSLog(@"Starting #3");
sleep(3);
NSLog(@"Finishing #3");
}];
如果您不想要 serial NSOperationQueue
,您可以使用标准并发队列,但只需使每个操作都依赖于前一个操作。您将在不使用串行队列的情况下实现您正在寻找的串行行为。
例如:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *operation;
NSOperation *previousOperation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Starting #1");
sleep(3);
NSLog(@"Finishing #1");
}];
[queue addOperation:operation];
previousOperation = operation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Starting #2");
sleep(3);
NSLog(@"Finishing #2");
}];
[operation addDependency:previousOperation];
[queue addOperation:operation];
previousOperation = operation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Starting #3");
sleep(3);
NSLog(@"Finishing #3");
}];
[operation addDependency:previousOperation];
[queue addOperation:operation];
您还可以使用dispatch_queue_create
. 除了使用 GCD 而不是NSOperationQueue
.
例如:
dispatch_queue_t queue = dispatch_queue_create("com.ConnerDouglass.operationtest", 0);
dispatch_async(queue, ^{
NSLog(@"Starting #1");
sleep(3);
NSLog(@"Finishing #1");
});
dispatch_async(queue, ^{
NSLog(@"Starting #2");
sleep(3);
NSLog(@"Finishing #2");
});
dispatch_async(queue, ^{
NSLog(@"Starting #3");
sleep(3);
NSLog(@"Finishing #3");
});
我认为这是一个有趣的解决方案:https ://github.com/berzniz/Sequencer
像这样的东西怎么样:
-(void)start
{
// Start the async chain
[self performSelectorInBackground:@selector(action1) withObject:nil];
}
-(void)notifyDone:(NSNumber *)taskID
{
NSLog(@"Done with task #%i", taskID.intValue);
}
-(void)action1
{
// Do some fancy async stuff here
// Now, we are done. Notify the main thread that task 1 is complete.
[self performSelectorOnMainThread:@selector(nofityDone:) withObject:[NSNumber numberWithInt:1] waitUntilDone:YES];
// Move onto the next task once the main thread is done handling the notification
[self action2];
}
-(void)action2
{
// Do the same sort of thing as "action1" did, then call he next method
}