First off, NSOperationQueue
let you enqueue operations, that is, some sort of asynchronous operations with a start
method, a cancel
method and a few observable properties, while with a dispatch queue one can submit a block or a closure or a function to a dispatch queue, which will be then executed.
An "Operation" is semantically fundamentally different than a block (or closure, function). An operation has an underlying asynchronous task, while a block (closure or functions) is just that.
What comes close to an NSOperation
, though, is an asynchronous function, e.g.:
func asyncTask(param: Param, completion: (T?, Error?) ->())
Now with Futures we can define the same asynchronous function like:
func asyncTask(param: Param) -> Future<T>
which makes such asynchronous functions quite handy.
Since futures have combinator functions like map
and flatMap
and so on, we can quite easily "emulate" the "dependency" feature of NSOperation
, just in a more powerful, more concise and more comprehensible way.
We can also implement some sort of NSOperationQueue
with a few lines of code based solely on GCD, say a "TaskQueue" and with basically the same features, like "maxConcurrentTasks" and can use it to enqueue task functions (not operations), in just a more powerful, more concise and a more comprehensible way as well. ;)
In order to get a cancelable operation, you need to create a subclass of NSOperation
- while you can create a async function "ad-hod" - inline.
Also, since cancellation is an independent concept, we can assume, that there exists some library whose implementation is solely based on GCD which solves this problem in the, uhm, the usual way ;) It may look like this:
self.cancellationRequest = CancellationRequest()
self.asyncTask(param: param, cancellationToken: cr.token).map { result in
...
}
and later:
override func viewWillDisappear(_ animated: animated) {
super.viewWillDisappear(animated)
self.cancellationRequest.cancel()
}
So, IMHO there's really no reason to use clunky NSOperation
and NSOperationQueue
, and there's no reason any more for subclassing NSOperation
, which is quite elaborate and surprising difficult, unless you don't care about data races.