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
存在一些实际缺点,我不想重复样板代码的开销,我相信这是大多数人在比较这些方法时唯一提到的事情。 这里还有更多重要的事情要提到:
-
Operations
是NSOperations
,正在为所有子类带来动态分配。 目前还没有Swift的对手,并且有理由相信不会因为这里提到的接下来的几件事 - 他们使用KVC和KVO ,这在Swift中仍然是未知的概念,并且极不可能在不久的将来实现。
- 我们没有
Operation
结果的无状态返回,因为Operation
的completementBlock无效。 因此,我们需要在Operation
上创建可读的属性(状态),以便将结果传回。 任何一种附加状态都会导致附加的内存管理复杂性 -
Operations
可以吸引开发人员“统一”使用它们,即使是琐碎的任务,也可以包装简单的代码以“遵循方法”…… - 单元测试中的复杂性更高,需要制作一些帮助程序
OperationQueue
模拟以能够正确测试它 - 有时它们只是成为所有业务逻辑的转储,几乎违反了所有SOLID原则。 如果有的话,
Operations
应该大部分都是样板,仅带有1+个方法调用和1+个结果属性,恕我直言。
同样,在观看WWDC 2015视频时,我找不到任何不可替代的关键功能。 当然,它们是一个有效的概念,有时可以将需要原子执行的一系列任务很好地封装在其中,但是在类似客户端的情况下,我们应该询问API架构本身是否有问题,并且而是在服务器端封装复杂性。
我创建了一个非常小的存储库,并比较了执行异步任务的3种最常见的方法。