使用NSOperation以及NSOperationQueue

使用NSOperation以及NSOperationQueuehtml

 

NSOperation vs. Grand Central Dispatch (GCD)并发

在Mac OS X v10.6和iOS4以前,NSOperation 与 NSOperationQueue 不一样于GCD,他们使用了彻底不一样的机制。app

从Mac OS X v10.6和iOS4开始,NSOperation 和 NSOperationQueue是创建在GCD上的。做为一种通例,苹果推荐使用最高级别的抽象,然而当评估显示有须要时,会忽然降到更低级别。ide

如下是对二者的快速比较,它会帮助你决定什么时候何地去使用GCD或者NSOperation和NSOperationQueue;函数

  • GCD是一种轻量级的方法来表明将要被并发执行的任务单位。你并不须要去计划这些任务单位;系统会为你作计划。在块(block)中添加依赖会是一件使人头疼的事情。取消或者暂停一个块会给一个开发者产生额外的工做!:]
  • NSOperation和NSOperationQueue 对比GCD会带来一点额外的系统开销,可是你能够在多个操做(operation)中添加附属。你能够重用操做,取消或者暂停他们。NSOperation和 Key-Value Observation (KVO)是兼容的;例如,你能够经过监听NSNotificationCenter去让一个操做开始执行。

 

NSOperation API测试

NSOperation 类有一个至关简短的声明。要定制一个操做,能够遵循如下步骤:spa

  1. 继承NSOperation类
  2. 重写“main”方法
  3. 在“main”方法中建立一个“autoreleasepool”
  4. 将你的代码放在“autoreleasepool”中(ARC中也须要放在autoreleasepool中,这是为了兼容MRC代码)

 

为了你可以测试代码,请新建一个类,继承自NSOperation,写成以下的形式:3d

 

以后再进行操做:htm

注意,只有将一个任务添加进了队列当中,这个任务才会被执行.对象

如下代码是并发执行2个任务,队列的最大并发数是4:

 

任务具备的优先级:

当你添加了操做到一个队列时,在对操做调用“start”方法以前,NSOperationQueue会浏览全部的操做。那些有较高优先级的操做会被先执行。有同等优先级的操做会按照添加到队列中的顺序去执行(先进先出)。
(历史注释:在1997年,火星车中的嵌入式系统遭遇过优先级反转问题,也许这是说明正确处理优先级和互斥锁的最昂贵示例了。想对这一事件的背景知识有更多的了解,能够看这个网址: http://research.microsoft.com/en-us/um/people/mbj/Mars_Pathfinder/Mars_Pathfinder.html 

 

请添加以下的延迟方法:

 

先开始任务,1s钟以后cancel掉一个任务:

 

每一个任务结束后都会有一个回调能够表示任务结束:

 

任务之间的从属关系:

 

如下来点总结:

  • 要常常检查isCancelled属性。若是操做不须要被执行了,你就不想在后台去运行它了!(你从外面设置了cancell后,你是须要在方法里面来实现cancell的哦,注意,亲)
  • 你并不须要重写“start”方法。然而,若是你决定去重写“start”方法,就必须处理好像isExecuting, isFinished, isConcurrent 和 isReady这些属性。不然你的操做类不会正确的运做。
  • 你一旦添加了一个操做到一个队列(NSOperationQueue的一个实例)中,就要负责释放它(若是你不使用ARC的话)。NSOperationQueue 得到操做对象的全部权,调用“start”方法,而后结束时负责释放它。
  • 你不能重用一个操做对象。一旦它被添加到一个队列中,你就丧失了对它的全部权。若是你想再使用同一个操做类,就必须建立一个新的实例变量。
  • 一个结束的操做不能被重启。
  • 若是你取消了一个操做,它不会立刻就发生。它会在将来的某个时候某人在“main”函数中明确地检查isCancelled == YES 时被取消掉;不然,操做会一直执行到完成为止。(见上图)
  • 一个操做是否成功地完成,失败了,或者是被取消了,isFinished的值总会被设置为YES。因此千万不要以为isFinished == YES就表示全部的事情都顺利完成了 — 特别的,若是你在代码里面有从属性(dependencies),就要更加注意!

 

NSOperationQueue API

查看当前并发操做的全部任务:

 

挂起与恢复操做:

This method suspends or resumes the execution of operations. Suspending a queue prevents that queue from starting additional operations. In other words, operations that are in the queue (or added to the queue later) and are not yet executing are prevented from starting until the queue is resumed. Suspending a queue does not stop operations that are already running.

这个方法会挂起或者恢复一个执行的任务.挂起一个队列能够阻止该队列中没有开始的任务.换句话说,在任务队列中尚未开始执行的任务是会被挂起的,直到这个挂起操做被恢复.挂起一个队列不会让一个已经执行的任务中止哦,亲.

 

取消全部操做:

要取消一个队列中的全部操做,你只要简单的调用“cancelAllOperations”方法便可。还记得以前提醒过常常检查NSOperation中的isCancelled属性吗?
缘由是“cancelAllOperations”并无作太多的工做,他只是对队列中的每个操做调用“cancel”方法 — 这并无起很大做用!:] 若是一个操做并无开始,而后你对它调用“cancel”方法,操做会被取消,并从队列中移除。然而,若是一个操做已经在执行了,这就要由单独的操做去识 别撤销(经过检查isCancelled属性)而后中止它所作的工做。

 

简单的block形式的队列任务:

 

以上就基本上讲完了怎么使用NSOperation以及NSOperationQueue了,亲.

相关文章
相关标签/搜索