NSOperation vs Grand Central Dispatch

125,589

Solution 1

GCD is a low-level C-based API that enables very simple use of a task-based concurrency model. NSOperation and NSOperationQueue are Objective-C classes that do a similar thing. NSOperation was introduced first, but as of 10.5 and iOS 2, NSOperationQueue and friends are internally implemented using GCD.

In general, you should use the highest level of abstraction that suits your needs. This means that you should usually use NSOperationQueue instead of GCD, unless you need to do something that NSOperationQueue doesn't support.

Note that NSOperationQueue isn't a "dumbed-down" version of GCD; in fact, there are many things that you can do very simply with NSOperationQueue that take a lot of work with pure GCD. (Examples: bandwidth-constrained queues that only run N operations at a time; establishing dependencies between operations. Both very simple with NSOperation, very difficult with GCD.) Apple's done the hard work of leveraging GCD to create a very nice object-friendly API with NSOperation. Take advantage of their work unless you have a reason not to.

Caveat: On the other hand, if you really just need to send off a block, and don't need any of the additional functionality that NSOperationQueue provides, there's nothing wrong with using GCD. Just be sure it's the right tool for the job.

Solution 2

In line with my answer to a related question, I'm going to disagree with BJ and suggest you first look at GCD over NSOperation / NSOperationQueue, unless the latter provides something you need that GCD doesn't.

Before GCD, I used a lot of NSOperations / NSOperationQueues within my applications for managing concurrency. However, since I started using GCD on a regular basis, I've almost entirely replaced NSOperations and NSOperationQueues with blocks and dispatch queues. This has come from how I've used both technologies in practice, and from the profiling I've performed on them.

First, there is a nontrivial amount of overhead when using NSOperations and NSOperationQueues. These are Cocoa objects, and they need to be allocated and deallocated. In an iOS application that I wrote which renders a 3-D scene at 60 FPS, I was using NSOperations to encapsulate each rendered frame. When I profiled this, the creation and teardown of these NSOperations was accounting for a significant portion of the CPU cycles in the running application, and was slowing things down. I replaced these with simple blocks and a GCD serial queue, and that overhead disappeared, leading to noticeably better rendering performance. This wasn't the only place where I noticed overhead from using NSOperations, and I've seen this on both Mac and iOS.

Second, there's an elegance to block-based dispatch code that is hard to match when using NSOperations. It's so incredibly convenient to wrap a few lines of code in a block and dispatch it to be performed on a serial or concurrent queue, where creating a custom NSOperation or NSInvocationOperation to do this requires a lot more supporting code. I know that you can use an NSBlockOperation, but you might as well be dispatching something to GCD then. Wrapping this code in blocks inline with related processing in your application leads in my opinion to better code organization than having separate methods or custom NSOperations which encapsulate these tasks.

NSOperations and NSOperationQueues still have very good uses. GCD has no real concept of dependencies, where NSOperationQueues can set up pretty complex dependency graphs. I use NSOperationQueues for this in a handful of cases.

Overall, while I usually advocate for using the highest level of abstraction that accomplishes the task, this is one case where I argue for the lower-level API of GCD. Among the iOS and Mac developers I've talked with about this, the vast majority choose to use GCD over NSOperations unless they are targeting OS versions without support for it (those before iOS 4.0 and Snow Leopard).

Solution 3

GCD is a low-level C-based API.
NSOperation and NSOperationQueue are Objective-C classes.
NSOperationQueue is objective C wrapper over GCD. If you are using NSOperation, then you are implicitly using Grand Central Dispatch.

GCD advantage over NSOperation:
i. implementation
For GCD implementation is very light-weight
NSOperationQueue is complex and heavy-weight

NSOperation advantages over GCD:

i. Control On Operation
you can Pause, Cancel, Resume an NSOperation

ii. Dependencies
you can set up a dependency between two NSOperations
operation will not started until all of its dependencies return true for finished.

iii. State of Operation
can monitor the state of an operation or operation queue. ready ,executing or finished

iv. Max Number of Operation
you can specify the maximum number of queued operations that can run simultaneously

When to Go for GCD or NSOperation
when you want more control over queue (all above mentioned) use NSOperation and for simple cases where you want less overhead (you just want to do some work "into the background" with very little additional work) use GCD

ref:
https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http://nshipster.com/nsoperation/

Solution 4

Another reason to prefer NSOperation over GCD is the cancelation mechanism of NSOperation. For example, an App like 500px that shows dozens of photos, use NSOperation we can cancel requests of invisible image cells when we scroll table view or collection view, this can greatly improve App performance and reduce memory footprint. GCD can't easily support this.

Also with NSOperation, KVO can be possible.

Here is an article from Eschaton which is worth reading.

Solution 5

GCD is indeed lower-level than NSOperationQueue, its major advantage is that its implementation is very light-weight and focused on lock-free algorithms and performance.

NSOperationQueue does provide facilities that are not available in GCD, but they come at non-trivial cost, the implementation of NSOperationQueue is complex and heavy-weight, involves a lot of locking, and uses GCD internally only in a very minimal fashion.

If you need the facilities provided by NSOperationQueue by all means use it, but if GCD is sufficient for your needs, I would recommend using it directly for better performance, significantly lower CPU and power cost and more flexibility.

Share:
125,589
SundayMonday
Author by

SundayMonday

Hey!

Updated on October 04, 2021

Comments

  • SundayMonday
    SundayMonday over 2 years

    I'm learning about concurrent programming for iOS. So far I've read about NSOperation/NSOperationQueue and GCD. What are the reasons for using NSOperationQueue over GCD and vice versa?

    Sounds like both GCD and NSOperationQueue abstract away the explicit creation of NSThreads from the user. However the relationship between the two approaches isn't clear to me so any feedback to appreciated!