Nsoperation VS Grand Central Dispatch

NSOperation vs Grand Central Dispatch

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.

NSOperationQueue vs NSOperation vs GCD

GCD is low level C-based API.

NSOperation and NSOperationQueue are Objective-C classes that are based on GCD and simplify execution prioritisation and cancellation.

Advantages of NSOperationQueue over GCD include:

  1. It is easy to cancel or suspend an operation if it is in queue it can be stopped if it is running.

  2. You can define the maximum number of concurrent operations.

  3. You can make dependencies between distinct instances of NSOperation.

2017 / Swift 3.1 - GCD vs NSOperation

I see them each still having their own purpose. I just recently rewatched the 2015 WWDC talk about this (Advanced NSOperations), and I see two main points here.

Run Time & User Interaction

From the talk:

NSOperations run for a little bit longer than you would expect a block to run, so blocks usually take a few nanoseconds, maybe at most a millisecond, to execute.

NSOperations, on the other hand, can be much longer, for anywhere from a couple of milliseconds to even several minutes

The example they talk about is in the WWDC app, where there exists an NSOperation that has a dependency on having a logged in user. The dependency NSOperation presents a login view controller and waits for the user to authenticate. Once finished, that NSOperation finishes and the NSOperationQueue resumes it's work. I don't think you'd want to use GCD for this scenario.

Subclassing

Since NSOperations are just classes, you can subclass them to get more reusability out of them. This isn't possible with GCD.

Example: (Using the WWDC login scenario from above)

You have many NSOperations in your code base that are associated with a user interaction that requires them to be authenticated. (Liking a video, in this example.) You could extend NSOperation to create an AuthenticatedOperation, then have all those NSOperations extend this new class.

What is the NSOperations' advantage compared wih Grand Central Dispatch(GCD)?

'NSOperation' gives you possibility to specify maximal number of concurreny request using setMaxConcurrentOperationCount: method which is often really nice thing to have.

Also NSOperation let you to specify pretty complex dependencies between some operations using addDependency: method. You can tell that some execution of some operation should start only when some others operations finished. Of course you can achieve the same efect using GCD but this will fast become pretty overkill as with many dependencies nested blocks will be not the cleanest solution.

When it comes to description of GDC and NSOperationsQueue's there isthis article. I found it to be really helpfulf.

//EDIT
Also, it seems NSOperation's are more object oriented approach which give you possibility to specify logic of some request to be fully isolated into NSOperation's subclass.

Difference between Dispatch Queue and NSOperationQueue

NSOperationQueue can be more suitable for long-running operations that may need to be cancelled or have complex dependencies. GCD dispatch queues are better for short tasks that should have minimum performance and memory overhead.

It is possible to cancel operations that have been enqueued in an NSOperationQueue (as far as the operations support it). When you enqueue a block in a GCD dispatch queue, it will definitely be executed at some point.

check the below link,it may be helpful to you.

Operation Queue vs Dispatch Queue for iOS Application

NSOperationQueue vs GCD

NSOperationQueue is built on GCD as of iOS 4. Use the simplest API for the task at hand.Measure if it's a performance problem and then reevaluate if needed.dispatch_async is lower level, usually C-type stuff (but not limited to), and is good for one-shot and sequential type deals. NSOperationQueues are higher level, Objective-C stuff, and are good if you are adding a lot of operations at various points in your code, and/or need to manage concurrency, priorities and dependencies.

Why should I choose GCD over NSOperation and blocks for high-level applications?

The point being made here is the same one that Chris Hanson states in his article "When to use NSOperation vs. GCD":

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.

In general, I agree with this. NSOperation and NSOperationQueue provide support for dependencies and one or two other things that GCD blocks and queues don't have, and they abstract away the lower-level details of how the concurrent operations are implemented. If you need that functionality, NSOperation is a very good way to go.

However, after working with both, I've found myself replacing all of my NSOperation-based code with GCD blocks and queues. I've done this for two reasons: there is significant overhead when using NSOperation for frequent actions, and I believe my code is cleaner and more descriptive when using GCD blocks.

The first reason comes from profiling in my applications, where I found that the NSOperation object allocation and deallocation process took a significant amount of CPU resources when dealing with small and frequent actions, like rendering an OpenGL ES frame to the screen. GCD blocks completely eliminated that overhead, leading to significant performance improvements.

The second reason is more subjective, but I believe that my code is cleaner when using blocks than NSOperations. The quick capture of scope allowed by a block and the inline nature of them make for less code, because you don't need to create custom NSOperation subclasses or bundle up parameters to be passed into the operation, and more descriptive code in my opinion, because you can place the code to be run in a queue at the point where it is fired off.

Again, its a matter of preference, but I've found myself using GCD more, even in otherwise more abstracted Cocoa applications.

(iOS) dispatch_async() vs. NSOperationQueue

NSOperation* classes are the higher level api. They hide GCD's lower level api from you so that you can concentrate on getting the task done.

The rule of thumb is: Use the api of the highest level first and then degrade based on what you need to accomplish.

The advantage of this approach is that your code stays most agnostic to the specific implementation the vendor provides.
In this example, using NSOperation, you'll be using Apple's implementation of execution queueing (using GCD). Should Apple ever decide to change the details of implementation behind the scenes they can do so without breaking your application's code.

One such example would be Apple deprecating GCD and using a completely different library (which is unlikely because Apple created GCD and everybody seems to love it).

Regarding the matter i recommend consulting the following resources:

  • http://nshipster.com/nsoperation/
  • https://cocoasamurai.blogspot.de/2009/09/guide-to-blocks-grand-central-dispatch.html
  • https://cocoasamurai.blogspot.de/2009/09/making-nsoperation-look-like-gcd.html
  • https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift
  • https://developer.apple.com/documentation/foundation/operationqueue
  • Video: Advanced NSOperations, WWDC 2015, Session 226
  • Sample code: Advanced NSOperations, WWDC 2015
  • Video: Building Responsive and Efficient Apps with GCD, WWDC 2015, Session 718

Now, regarding your specific questions:

What are the differences between dispatch_*() and NSOperationQueue, [...]

See above.

[...] and is there any reason (technical, performance, stylistic, or otherwise) that I should use one over the other?

If the NSOperation stuff gets your job done, use it.

Is NSOperationQueue just an Objective-C wrapper around dispatch_async, or is there more to it than that?

Yes, it basically is. Plus features like operation dependencies, easy start/stop.

Amendment

To say, use the highest level api first might sound intriguing. Of course, if you need a quick way to run code on a specific thread, you don't want to write a whole lot of boilerplate code which makes the use of lower level C functions perfectly valid:

dispatch_async(dispatch_get_main_queue(), ^{
do_something();
});

But consider this:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
do_something();
}];

I'd recommend the latter because most of what you'll write is Objective-C anyway so why not embrace its expressiveness?

Which tasks are more suitable to NSOperation than GCD?

NSOperation is built on top of GCD, so the question is more about whether you use NSOperation or pass a block directly to GCD.

An NSOperation is bulky and needs more boiler-plate codes to set it up, but it has a lot more functionality. You can create the same NSOperation subclass in various parts of your code and put them into the queue and run it.

Passing a block to GCD by e.g. dispatch_async is quick and disposable. You typically don't reuse a block anywhere else; you just set up a block which is executed only at that point of the code, passes it to the GCD or other APIs, and quickly go on.

So each has its merits.

NSOperation vs GCD for updating view

Same thing, but not really ... !

As @BradLarson said here
NSOperation vs Grand Central Dispatch

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).



Related Topics



Leave a reply



Submit