I have a number of tasks I need to execute serially but the task includes next block in a completion block.
What is a good technique for doing these tasks one at a time, starting the next task after the current one completes its completion block?
Is there a technique other than a NSOperation subclass with a serial NSOperationQueue?
Standard solutions:
NSOperationQueue
with maxConcurrentOperationCount
of 1
. You say you don't want to do that, but you don't say why. Serial queues are the most logical solution.
For example:
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");
}];
If you don't want a serial NSOperationQueue
, you can use a standard concurrent queue, but just make each operation dependent upon the prior one. You'll achieve the serial behavior you're looking for without using a serial queue.
For example:
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];
You could also create a GCD serial queue with dispatch_queue_create
. It achieves the same thing as the first option, except using GCD instead of NSOperationQueue
.
For example:
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");
});
I think this is an interesting solution: https://github.com/berzniz/Sequencer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With