在执行任务之前等待队列中的所有操作完成

我有一个Operation子类和操作队列,maxConcurrentOperationCount = 1。

这按顺序执行我的操作,我添加它们是好的,但现在我需要等到所有操作完成后再运行另一个进程。

我正在尝试使用通知组,但是一旦将操作添加到队列中就会在for循环中运行,通知组将触发..如何在运行另一个进程之前等待所有操作离开队列?

for (index, _) in self.packArray.enumerated() { myGroup.enter() let myArrayOperation = ArrayOperation(collection: self.outerCollectionView, id: self.packArray[index].id, count: index) myArrayOperation.name = self.packArray[index].id downloadQueue.addOperation(myArrayOperation) myGroup.leave() } myGroup.notify(queue: .main) { // do stuff here } 

您可以使用操作依赖项在完成一系列其他操作后启动某些操作:

 let operationQueue = OperationQueue() let completionOperation = BlockOperation { // do something } for object in objects { let operation = ... completionOperation.addDependency(operation) operationQueue.addOperation(operation) } OperationQueue.main.addOperation(completionOperation) 

合适的解决方案是KVO

首先在循环之前添加观察者(假设queueOperationQueue实例)

 queue.addObserver(self, forKeyPath:"operations", options:.new, context:nil) 

然后实施

 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if object as? OperationQueue == queue && keyPath == "operations" { if queue.operations.isEmpty { // Do something here when your queue has completed self.queue.removeObserver(self, forKeyPath:"operations") } } else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } } 

编辑:

在Swift 4中,它更容易

声明属性:

 var observation : NSKeyValueObservation? 

并创建观察者

 observation = queue.observe(\.operationCount, options: [.new]) { [unowned self] (queue, change) in if change.newValue! == 0 { // Do something here when your queue has completed self.observation = nil } } 

我使用下一个解决方案:

 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) } }