iOS:运营(NSOperations)-为什么又来了?

GCD或运营

每当我问这两种排队任务方法之间的区别时,我都会得到类似的响应:

  • 随便使用GCD
  • 使用GCD进行简单的单个异步调用

但在以下情况下使用“ 操作”

  • 你想取消他们
  • 您想要一次执行更多任务
  • 当您要在依赖关系中执行它们时
  • 当您想优先执行时

这些建议听起来像GCD会缺少Operations的某些核心功能,但有人反复说Operations或多或少是围绕GCD的包装。

好吧,后者当然是正确的,而且运营似乎没有什么特别之处,您对GCD所做的事情实际上并不多,实际上,很多事情都以一种更轻松的方式,更易读,尽管个人偏见可能会起到一定的作用。与我们生活中的一切息息相关。 我可以在某种程度上说,Operations不能完全实现通过封装进行简单分配的任务,因为至少就我个人而言,仅使用GDC似乎更容易实现太多事情。

误解

但是,我认为应该对操作存在一些真正的误解:

1.取消应用程序并不会发生。 开发人员必须实现取消并在属性上设置KVC才能实现这一点, OperationQueue只是侦听它。 取消的实现方式与您在GCD中执行的方式相同。 这里没有魔术! 例如,如果需要取消异步URLSession ,则必须使用KVC更改状态以通知OperationQueue ,但是您仍然必须自己实现取消URLSession 。 实际上,您在这里还需要进行其他操作。

2.也可以使用 DispatchGroup 轻松地原子地执行任务组 ,这并不是OperationQueues能够单独执行的,实际上,使用GCD 可以使任务组更短,更容易且更精简。

3.再次依赖,当使用OperationQueue,不要只是开箱即用。 需要预先将操作链接为从属链接,并完成isFinish的所有开销,并且需要实现其余样板,以便该机制起作用。 我会说,在GCD的串行队列上使用Dispatch更具可读性,更容易理解,特别是在存在更多后续任务的情况下。
但是,如果要同步的任务本身本质上是异步的,则GCD变得更加易于使用。

如果只有一个附加的依赖关系,那么我们可以嵌套第二个任务。

如果还有更多,那么使用DispatchGroups是一件很容易的事情……

当依赖关系可能在单个任务和任务组之间时,还有很多要显示的东西,这就是GCD在操作性方面比操作性更出色的地方。 不过,这并不是经常发生的用例,因此,这并不是一个巨大的优势。

缺点

但是,恕我直言,使用Operations存在一些实际缺点,我不想重复样板代码的开销,我相信这是大多数人在比较这些方法时唯一提到的事情。 这里还有更多重要的事情要提到:

  • OperationsNSOperations ,正在为所有子类带来动态分配。 目前还没有Swift的对手,并且有理由相信不会因为这里提到的接下来的几件事
  • 他们使用KVCKVO ,这在Swift中仍然是未知的概念,并且极不可能在不久的将来实现。
  • 我们没有Operation结果的无状态返回,因为Operation的completementBlock无效。 因此,我们需要在Operation上创建可读的属性(状态),以便将结果传回。 任何一种附加状态都会导致附加的内存管理复杂性
  • Operations可以吸引开发人员“统一”使用它们,即使是琐碎的任务,也可以包装简单的代码以“遵循方法”……
  • 单元测试中的复杂性更高,需要制作一些帮助程序OperationQueue模拟以能够正确测试它
  • 有时它们只是成为所有业务逻辑的转储,几乎违反了所有SOLID原则。 如果有的话, Operations应该大部分都是样板,仅带有1+个方法调用和1+个结果属性,恕我直言。

同样,在观看WWDC 2015视频时,我找不到任何不可替代的关键功能。 当然,它们是一个有效的概念,有时可以将需要原子执行的一系列任务很好地封装在其中,但是在类似客户端的情况下,我们应该询问API架构本身是否有问题,并且而是在服务器端封装复杂性。

我创建了一个非常小的存储库,并比较了执行异步任务的3种最常见的方法。