A suitable solution is KVO
Before the loop adds an observer (it is assumed that the queue is an instance of OperationQueue )
queue.addObserver(self, forKeyPath:"operations", options:.new, context:nil)
Then do
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) } }
Edit:
Swift 4 makes it a lot easier.
Declare a property:
var observation : NSKeyValueObservation?
and create an observer
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 } }
source share