Search code examples
iosswiftgrand-central-dispatchnsoperation

2017 / Swift 3.1 - GCD vs NSOperation


I am diving a bit deeper into concurrency and have been reading extensively about GCD and NSOperation. However, a lot of posts like the canonic answer on SO are several years old.

It seemed to me that NSOperation main advantages used to be, at the cost of some performance:

  • "the way to go" generally for more than a simple dispatch as the highest level abstraction (built atop of GCD)
  • to make task manipulation (cancellation, etc.) a lot easier
  • to easily set up dependencies between tasks

Given GCD's DispatchWorkItem & block cancellation / DispatchGroup / qos in particular, is there really an incentive (cost-performance wise) to use NSOperation anymore for concurrency apart from cases where you need to be able to cancel a task when it began executing or query the task state ?

Apple seems to put a lot more emphasis on GCD, at least in their WWDC (granted it's more recent than NSOperation).


Solution

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