When to use NSOperation vs. GCD

Mac OS X has a number of concurrency mechanisms, and that increases with Snow Leopard. In addition to run loops, threads (both Cocoa and POSIX) and operations, Snow Leopard adds **Grand Central Dispatch** (GCD), a very lightweight way to represent units of work and the style of concurrency they need, and have the system figure out how to schedule them.

But wait, don’t we have that already in NSOperation? It shouldn’t surprise you in the least to learn that NSOperation, on Snow Leopard, is built atop GCD. However, there are a number of differences between the two, and for that reason people have started to ask “How should I decide which to use when?”

The straightforward answer is a general guideline for all application development:

> **Always use the highest-level abstraction available to you, and drop down to lower-level abstractions when measurement shows that they are needed.**

In this particular case, it means that when writing Cocoa applications, you should generally be using NSOperation rather than using GCD directly. Not because of a difference in efficiency, but because NSOperation provides a *higher-level abstraction* atop the mechanisms of GCD.

For example, you can set up a dependency between two NSOperations such that the second will only be run after the first is complete — even if they’re run on different queues. You can use KVO to observe the completion (or cancellation) of different operations — and you can create operations that support being cancelled in the first place. You can set a completion block to run after an application has finished. And you can, of course, create operations from blocks using *NSBlockOperation*.

You’ll also fit in better with Cocoa by using NSOperation in your high-level code. If you take a look at new Snow Leopard API on NSNotificationCenter, you’ll see one where you specify the NSOperationQueue on which you wish a notification to run a block.

Ultimately, you spend a little bit of overhead to use NSOperation instead of GCD, but you gain significant additional functionality that will be useful as you start to compose operations together. And that’s the biggest benefit of NSOperation: You can break up your application in terms of units of work that can not only be run on a queue, but also canceled, observed, and depended upon. This lets you easily define your data dependencies and ensure that you aren’t simply running code serially as a side-effect of locking.

9 Comments

  1. Colin Barrett
    September 8, 2009

    I actually feel the opposite. NSOperation’s heavy reliance on KVO makes it a real pain to use. I would rather re-imement something like cancelling or chaining myself than deal with KVO’s ugly API.

    A bit extreme, sure. But fighting that particular fight is just a real drag.

    Reply
  2. Chris Mear
    September 9, 2009

    Newbie question: Does this mean that one could write the same code to target 10.5 and 10.6, using NSOperation, and get the benefit of GCD backing on 10.6 while still retaining source-level compatibility with 10.5?

    Reply
  3. Pierre Bernard
    September 9, 2009

    I would love to see an example of somebody tying in NSOperationQueue with a table view to produce a representation of a list of concurrent and individually cancelable tasks. Much like the copy/move progress window in the Finder.

    Reply
  4. James Bucanek
    September 9, 2009

    Chris,

    Yes. In 10.6 NSOperation uses Grand Central Dispatch to do it’s work. So if you’ve already written, or continue to write, NSOperation methods you’ll benefit from GCD automatically on Snow Leopard while retaining backwards compatibility with Leopard.

    Reply
  5. Chris Mear
    September 9, 2009

    Brilliant, thanks for the response!

    Reply
  6. Alexander von Below
    July 22, 2012

    I wonder: Is you advice still valid now that we have blocks?

    Reply
  7. joel
    October 12, 2012

    Alexander,

    Yes as we now have NSBlockOperation so we can quickly put blocks on an operation queue

    Reply
  8. […] 延伸阅读:StackOverflow: NSOperation vs. Grand Central DispatchBlog: When to use NSOperation vs. GCD […]

    Reply
  9. […] The point being made here is the same one that Chris Hanson states in his article “When to use NSOperation vs. GCD“: […]

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *