I'm working on a framework and in order to ensure non blocking public methods, I'm using a NSOperationQueue
that puts all the public method calls into an operation queue and returns immediately.
There is no relation or dependencies between different operations and the only thing that matters is that the operations are started in FIFO order that is in the same order as they were added to the queue.
Here is an example of my current implementation (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];
}
I realised though that the order at which the operations are started is not necessarily the order at which they were added to the queue. For instance, if I call
[self.executor doTask:@"Task 1"];
[self.executor doTask:@"Task 2"];
Sometimes Task 2
is started after Task 1
.
The question is how can I ensure a FIFO execution start?
I could achieve it using _taskQueue.maxConcurrentOperationCount = 1;
but this would allow only 1 operation at once which I don't want. One operation should not block any other operation and they can run concurrently as long as they are started in the correct order.
I looked also into the NSOperationQueuePriority
property which would work If I knew the priorities of the calls which I don't. In fact, even if I sent the earlier added operation to NSOperationQueuePriorityHigh
and the second to NSOperationQueuePriorityNormal
the order is not guaranteed neither.
[self.executor doTask:@"Task 1" withQueuePriority:NSOperationQueuePriorityHigh];
[self.executor doTask:@"Task 2" withQueuePriority:NSOperationQueuePriorityNormal];
Output is sometimes
executing Task 2
executing Task 1
Any ideas?
thanks, Jan