Получать уведомления, когда NSOperationQueue завершает все задачи - PullRequest
89 голосов
/ 26 июня 2009

NSOperationQueue имеет waitUntilAllOperationsAreFinished, но я не хочу ждать его синхронно. Я просто хочу скрыть индикатор прогресса в пользовательском интерфейсе, когда очередь заканчивается.

Какой лучший способ сделать это?

Я не могу отправлять уведомления от моих NSOperation s, потому что я не знаю, какой из них будет последним, и [queue operations] может быть еще не пустым (или, что еще хуже - заполнено), когда уведомление получено.

Ответы [ 13 ]

0 голосов
/ 09 апреля 2018

без КВО

private let queue = OperationQueue()

private func addOperations(_ operations: [Operation], completionHandler: @escaping () -> ()) {
    DispatchQueue.global().async { [unowned self] in
        self.queue.addOperations(operations, waitUntilFinished: true)
        DispatchQueue.main.async(execute: completionHandler)
    }
}
0 голосов
/ 19 апреля 2017

Если вы используете эту операцию в качестве базового класса, вы можете передать блок whenEmpty {} в OperationQueue :

let queue = OOperationQueue()
queue.addOperation(op)
queue.addOperation(delayOp)

queue.addExecution { finished in
    delay(0.5) { finished() }
}

queue.whenEmpty = {
    print("all operations finished")
}
0 голосов
/ 26 июня 2009

Вы можете создать новый NSThread или выполнить селектор в фоновом режиме и ждать там. Когда NSOperationQueue заканчивается, вы можете отправить собственное уведомление.

Я думаю о чем-то вроде:

- (void)someMethod {
    // Queue everything in your operationQueue (instance variable)
    [self performSelectorInBackground:@selector(waitForQueue)];
    // Continue as usual
}

...

- (void)waitForQueue {
    [operationQueue waitUntilAllOperationsAreFinished];
    [[NSNotificationCenter defaultCenter] postNotification:@"queueFinished"];
}
...