Это более или менее то, что говорил jeffamaphone, но я добавил сущность, которая в общих чертах должна делать то, что вы просите.
Я создаю NSMutableArray
из NSOperationQueue
s, которые служат «очередью очередей». Каждый раз, когда вы добавляете объект BarrierOperation
, вы добавляете новую приостановленную очередь операций в конце. Это становится addingQueue
, к которому вы добавляете последующие операции.
- (void)addOperation:(NSOperation *)op {
@synchronized (self) {
if ([op isKindOfClass:[BarrierOperation class]]) {
[self addBarrierOperation:(id)op];
} else {
[[self addingQueue] addOperation:op];
}
}
}
// call only from @synchronized block in -addOperation:
- (void)addBarrierOperation:(BarrierOperation *)barrierOp {
[[self addingQueue] setSuspended:YES];
for (NSOperation *op in [[self addingQueue] operations]) {
[barrierOp addDependency:op];
}
[[self addingQueue] addOperation:barrierOp];
// if you are free to set barrierOp.completionBlock, you could skip popCallback and do that
__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]; // fresh empty queue to add to
}
Когда один NSOperationQueue
заканчивается, он выскакивает, и начинает работать следующий.
- (void)popQueue
{
@synchronized (self) {
NSAssert([_queueOfQueues count], @"should always be one to pop");
[_queueOfQueues removeObjectAtIndex:0];
if ([_queueOfQueues count]) {
// first queue is always running, all others suspended
[(NSOperationQueue *)_queueOfQueues[0] setSuspended:NO];
}
}
}
Я мог пропустить что-то важное. Дьявол кроется в деталях.
Для меня это немного пахнет домашним заданием. Если да, то скажите мне, какую оценку я получаю. :)
Приложение: через комментарий abhilash1912 другой, но похожий подход. Этот код проверен, поэтому он уже побеждает. Но он немного устарел (2 года или около того на сегодняшний день; использование некоторых устаревших методов). Более того, я сомневаюсь, является ли наследование от NSOperationQueue
лучшим путем, хотя он имеет преимущество в сохранении знакомства. В любом случае, если вы дочитали до этого места, возможно, вам стоит перечитать.
Если вы создадите или найдете лучший в мире класс BarrierQueue, сообщите нам об этом в комментариях или другим способом, чтобы его можно было связать.
person
Clay Bridges
schedule
19.03.2014