This is more or less what jeffamaphone was talking about , but I put a gist , which should, in a rough way, do what you ask.
I create NSMutableArrayof NSOperationQueues, which serves as a "queue of queues". Each time you add an object BarrierOperation, you end a new paused queue at the end of the queue. It becomes addingQueueto which you add subsequent operations.
- (void)addOperation:(NSOperation *)op {
@synchronized (self) {
if ([op isKindOfClass:[BarrierOperation class]]) {
[self addBarrierOperation:(id)op];
} else {
[[self addingQueue] addOperation:op];
}
}
}
- (void)addBarrierOperation:(BarrierOperation *)barrierOp {
[[self addingQueue] setSuspended:YES];
for (NSOperation *op in [[self addingQueue] operations]) {
[barrierOp addDependency:op];
}
[[self addingQueue] addOperation:barrierOp];
__block typeof(self) weakSelf = self;
NSOperation *popCallback = [NSBlockOperation blockOperationWithBlock:^{
[weakSelf popQueue];
}];
[popCallback addDependency:barrierOp];
[[self addingQueue] addOperation:popCallback];
[[self addingQueue] setSuspended:NO];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue setSuspended:YES];
[_queueOfQueues addObject:opQueue];
}
When one ends NSOperationQueue, it appears, and the next starts.
- (void)popQueue
{
@synchronized (self) {
NSAssert([_queueOfQueues count], @"should always be one to pop");
[_queueOfQueues removeObjectAtIndex:0];
if ([_queueOfQueues count]) {
[(NSOperationQueue *)_queueOfQueues[0] setSuspended:NO];
}
}
}
Perhaps I missed something important. The devil is in the details.
. , , .:)
: Via abhilash1912 , , , , . ( - 2 , ). , , NSOperationQueue , . , , , , .
BarrierQueue, , .