Concurrency By Turorials (2) - GCD与Operations

358

在使应用程序并发时,您将使用两个api: GCD(Grand Central Dispatch)和Operations。

这些技术既不是相互竞争也不是必须二选一。

事实上,Operations是建立在GCD之上的!

GCD

GCD是苹果实现的C的libdispatch库。其目的是根据资源的可用性,对可以并行运行的任务(方法或闭包)进行排队;然后在可用的处理器内核上执行任务。 虽然GCD在其实现中使用线程,但是作为开发人员,您不需要自己管理它们,所以也无法保证您的任务将针对哪个线程执行。 GCD为您管理的所有任务都放在GCD管理的先进先出(FIFO)队列中,提交给队列的每个任务都在系统管理的线程池中执行。

异步与同步

放入队列的工作可以同步运行,也可以异步运行。

当以同步方式运行任务时,您的应用程序将等待并阻塞当前的运行循环,直到执行完成,然后再继续下一个任务。

异步运行的任务将启动,但立即返回应用程序的执行。在执行第一个任务时,应用程序可以自由地运行其他任务。

任务队列是以FIFO的方式,只能保证什么时候开始,但并不能保证完成的先后顺序。

串行和并行队列

提交任务的队列也具有串行或并发的特性。

串行队列只有一个与之关联的线程,因此只允许在任何给定时间执行一个任务。

一个并发队列能够利用系统资源所能利用的所有线程。线程将根据需要在并发队列上创建和释放。

并发队列并不能保证在同一时间,会至少有一个任务正在被执行。比如遇到资源竞争的情况。

异步不等于并行

Operation

对于需要在后台一次性运行的常见任务,GCD非常有用。 当发现自己正在构建应该可重用的功能时,可能希望将该功能封装到类中。 通过子类化Operation,就可以实现。

Operation的子类

Operation是可以提交到OperationQueue的功能类,就像为GCD提交工作的闭包到DispatchQueue一样。 因为它们是类,并且可以包含变量,所以您可以知道操作在任何给定点处于什么状态。 操作可以存在于以下任何一种状态: •isReady •isExecuting •isCancelled •isFinished 与GCD不同,操作在默认情况下是同步运行的,而要使其异步运行则需要更多的工作。 虽然您可以自己直接执行操作,但由于其同步特性,这几乎永远都不是一个好的方式。

特性

Operation为任务提供了更好的控制,可以处理诸如取消任务、报告任务状态、将异步任务包装到操作中以及指定不同任务之间的依赖性等常见需求。

BlockOperation

有时发现自己正在处理一个大量使用操作的应用程序,但是您需要一个更简单的、类似gcd的闭包。如果您不想创建一个DispatchQueue,那么您可以使用BlockOperation类。 BlockOperation子类操作为您和管理一个或多个闭包的并发执行默认的全局队列。然而,作为一个实际的操作子类,您可以利用操作的所有其他特性。 BlockOperation是并发运行。如果需要它们串行运行,则需要用dispatch queue代替。

应该用哪一个

使用GCD还是Operation,并没有明确的表示。 对于只需要执行且并不需要保存的简单任务,GCD往往更容易使用。当需要跟踪或维护、取消作业的能力或者封装数据时,Operation提供了更多的功能。