Code at the end of the queue

NSOperation and NSOperationQueue are great and useful Foundation framework tools for asynchronous tasks. One thing puzzled me though: How can I run code after all my queue operations finish? The simple answer is: use dependencies between operations in the queue (unique feature of NSOperation). It's just 5 lines of code solution.

NSOperation dependency trick

with Swift it is just easy to implement as this:

extension Array where Element: NSOperation {  
    /// Execute block after all operations from the array.
    func onFinish(block: () -> Void) {
        let doneOperation = NSBlockOperation(block: block)
        self.forEach { [unowned doneOperation] in doneOperation.addDependency($0) }
        NSOperationQueue().addOperation(doneOperation)
    }
}

what happened? new NSBlockOperation depends on all operations from the array, as such will be executed at the end, after all operations finish.

Interesting note: dependency may be set between different queues 👍

Usage

[operation1, operation2].onFinish {
    print("all done")
}

or directly with NSOperationQueue

operationQueue.operations.onFinish {  
    print("blocks done")
}

neat!

Grand Central Dispatch trick

Of course I use GCD a lot (a way more often than NSOperation) because I found it convenient and fit to most of the cases. To build the same functionality I'd create dispatch_group_t and use it to notify when all tasks completed, like here:

let queue = dispatch_queue_create("my queue", DISPATCH_QUEUE_CONCURRENT)  
let group = dispatch_group_create()

// called when all blocks associated with the
// dispatch group have completed.
dispatch_group_notify(group, dispatch_get_main_queue()) {  
    print("done")
}

// dispatch asynchronous blocks
for idx in 0..<5 {  
    dispatch_group_async(group, queue) {
        print(idx)
    }
}

Not that neat as NSOperation.

Conclusion

Seriously I love 💓 this simple, small features of Swift that makes daily tasks so simple, yet powerful. If you work with NSOperations you may find it useful in daily hacking.