2017-04-05 64 views
8

我深入了解并发性,并广泛阅读关于GCD和NSOperation。但是,很多帖子,比如canon answer on SO已经有几年了。2017/Swift 3.1 - GCD vs NSOperation

这在我看来,NSOperation主要优势曾经是,某些性能成本:

  • “的路要走”,一般超过一个简单的调度为最高级别的抽象(之上构建的GCD)
  • 做任务操作(取消,等等)轻松很多
  • 轻松建立依赖性任务之间

由于GCD的DispatchWorkItem &块取消/特别DispatchGroup/qos,是真的有一种激励(性价比明智),以分开使用NSOperation了并发的,你需要能够取消任务情况下,当它开始执行或查询任务状态?

苹果似乎更重视GCD,至少在他们的WWDC(授予它比NSOperation更近)。

回答

4

我看到他们每个人仍然有自己的目的。我刚刚重新看了2015年WWDC关于这个(高级NSOperations)的讨论,我在这里看到两个要点。

运行时间&用户交互

从谈话:

NSOperations运行一点点的时间比你所期望的一个块的运行,所以块通常需要几纳秒,也许最多一毫秒即可执行。

NSOperations,在另一方面,可以从几毫秒更长,任何地方,甚至几分钟

他们谈的是在WWDC app,其中存在一个的NSOperation的例子依赖于拥有登录用户。依赖项NSOperation提供了一个登录视图控制器并等待用户进行身份验证。一旦完成,该NSOperation完成,NSOperationQueue恢复工作。我认为你不想在这种情况下使用GCD。

子类

由于NSOperations只是类,你可以继承他们得到更多重用了出来。这对于GCD来说是不可能的。

例子:(从上面使用WWDC登录的情况)

你在你的代码库很多NSOperations了与该要求他们进行身份验证的用户交互关联。 (在这个例子中,喜欢视频。)你可以扩展NSOperation来创建AuthenticatedOperation,然后让所有这些NSOperations扩展这个新类。

1

首先,NSOperationQueue让你排队操作,也就是说,某种具有start法,cancel方法和一些可观察性异步操作的,同时与调度队列中的一个可以提交一个或一个关闭函数到一个调度队列,然后将执行。

“操作”是比块(或封闭件,功能)语义根本不同的。一个操作有一个底层的异步任务,而一个块(闭包或函数)就是这样。

什么接近的NSOperation,虽然是一个异步功能,如:

func asyncTask(param: Param, completion: (T?, Error?) ->()) 

现在用期货我们可以这样定义同异步函数:

func asyncTask(param: Param) -> Future<T> 

这使得这种异步功能非常方便。

由于期货有像mapflatMap等组合子功能,我们可以很容易地“模仿”的NSOperation“依赖”功能,只需在一个更强大,更简洁,更易于理解的方式。

我们也可以实现某种NSOperationQueue与仅基于GCD基础的几行代码,说“任务队列”,并使用基本相同的功能,如“maxConcurrentTasks”,可以用它来排队任务功能(而不是操作),只是一种更强大,更简洁,更易理解的方式。 ;)

为了获得可取消操作,您需要创建NSOperation的子类 - 而您可以创建异步函数“ad-hod” - 内联。

此外,由于取消是一个独立的概念,我们可以假设,存在一些库,其实现完全基于GCD,它以通常的方式解决了这个问题;)可能看起来像这样:

self.cancellationRequest = CancellationRequest() 
self.asyncTask(param: param, cancellationToken: cr.token).map { result in 
    ... 
} 

及更高版本:

override func viewWillDisappear(_ animated: animated) { 
    super.viewWillDisappear(animated) 
    self.cancellationRequest.cancel() 
} 

因此,恕我直言,真的没有理由使用笨重NSOperationNSOperationQueue,而且也没有任何理由更多的子类NSOperation,这是相当复杂和令人惊讶的困难,除非你不关心数据竞赛。