Block Operation
BlockOperation
is initialized with a block to execute. This is probably the most handy and versatile operation class, as it can be used to execute a block on a queue, just like dispatch_async
but with the features of operations such as dependencies, observers and conditions.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let show = BlockOperation {
self.navigationController?.pushViewController(viewController, animated: true)
}
show.addCondition(MutuallyExclusive<UIViewController>())
show.addObserver(FinishedObserver { _, errors in
dispatch_async(Queue.Main.queue) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
})
queue.addOperation(show)
}
The example above uses a BlockOperation
to push a view controller onto a navigation controller within a UITableViewDelegate
callback. We can add a condition that prevents other UIViewController
based operations from running, and an observer to deselect the row when it completes.
In this example, the BlockOperation
is initialized with a dispatch_block_t
which is executed on the main queue. This makes it ideal for UI based operations such as this. In addition the BlockOperation
will automatically finish after the block exists. Therefore it can only be used for synchronous tasks.
To execute the block directly on the operation queue, we must use a different initializer.
let operation = BlockOperation { (continuation: BlockOperation.ContinuationBlockType) in
doSomeWork()
continuation(error: nil)
}
In the above example, the block receives a continuation block as an argument. This continuation block must be called to finish the operation. It accepts a ErrorType?
which means that the block can finish with an error if needed.
Always execute the continuation block
If the continuation block is not called the queue can potentially become blocked. There is probably going to be some improvements in regard to this. Firstly making the closure easier to to write, and potentially automatically adding a
TimeoutObserver
toBlockOperation
when in debug configuration.
When using BlockOperation
on the queue with a continuation argument, it is also possible to start other asynchronous tasks which have completion handers. For these cases the continuation block can be executed inside the completion handler. This can be useful to bridge to other asynchronous systems.
Updated less than a minute ago