In OS X “Yosemite” and iOS 8, Apple introduced the ability to cancel blocks dispatched onto GCD queues. Previously, one had to use
NSOperations or rely on hacks to achieve this. Unfortunately, many people don’t realize this functionality now exists in GCD, and using it is quite easy.
Suppose we’re scheduling a block for delayed execution with
To cancel the block before it gets a chance to execute, we first have to obtain a reference to it. We can do this by creating a wrapper object of type
Now if we place a call to
dispatch_block_cancel immediately after the call to
dispatch_after, you’ll notice the block never executes:
One thing to note is that
dispatch_block_cancel is not pre-emptive. If the worker block is in the middle of a long-running operation,
dispatch_block_cancel won’t force-terminate it. To do this, we have to periodically test for cancellation with
dispatch_block_testcancel. Here’s an example:
And that’s all it takes to cancel blocks in GCD!