使用NSOperation以及NSOperationQueue

NSOperation vs. Grand Central Dispatch (GCD)

在Mac OS X v10.6和iOS4之前,NSOperation 与 NSOperationQueue
不同于GCD,他们使用了完全不同的机制。

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

以下是对两者的快速比较,它会帮助你决定何时何地去使用GCD或者NSOperation和NSOperationQueue;

  • GCD是一种轻量级的方法来代表将要被并发执行的任务单位。你并不需要去计划这些任务单位;系统会为你做计划。在块(block)中添加依赖会是一件令人头疼的事情。取消或者暂停一个块会给一个开发者产生额外的工作!:]

  • NSOperation和NSOperationQueue
    对比GCD会带来一点额外的系统开销,但是你可以在多个操作(operation)中添加附属。你可以重用操作,取消或者暂停他们。NSOperation和 Key-Value Observation
    (KVO)
    是兼容的;例如,你可以通过监听NSNotificationCenter去让一个操作开始执行。

NSOperation API

NSOperation 类有一个相当简短的声明。要定制一个操作,可以遵循以下步骤:

  1. 继承NSOperation类

  2. 重写“main”方法

  3. 在“main”方法中创建一个“autoreleasepool”

  4. 将你的代码放在“autoreleasepool”中(ARC中也需要放在autoreleasepool中,这是为了兼容MRC代码)

为了你能够测试代码,请新建一个类,继承自NSOperation,写成如下的形式:

之后再进行操作:

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

以下代码是并发执行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了,亲.

时间: 2024-09-30 19:01:45

使用NSOperation以及NSOperationQueue的相关文章

IOS中的多线程【二】— NSOperation和NSOperationQueue

NSOperationQueue是一套基于Objective-c语言的API. GCD与NSOperationQueue的优缺点: NSOperationQueue:比较安全 GCD:没有NSOperationQueue安全,但使用起来简单,快速,还提供了一些操控底层的方法.实际开发中还是以GCD为主. NSOperationQueue实现多线程流程 1.定义一个任务队列. 2.定义一个任务. 3.把任务添加到队列中.一旦任务被添加到队列中,任务会马上被调度执行. 任务队列(NSOperatio

多线程之NSOperation和NSOperationQueue

这篇文章里我将不过多的谈及理论知识,这些东西会的自然会,不会的,看多了也是云里雾里.下面我讲更多的用代码+注释的方式来讲如何使用NSOperation和NSOperationQueue. 1.NSOperation.是抽象类,不能够直接使用,而是使用子类NSInvocationOperation和NSBlockOperation来实际执行任务.NSOperation本身和多线程是没有任何关系的,她只是封装了一个代码段和数据去实现一个功能. 1.1.NSInvocationOperation,基于

ios多线程之NSOperation和NSOperationQueue

NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 1.NSOperation和NSOperationQueue实现多线程的具体步骤 2.先将需要执行的操作封装到一个NSOperation对象中 3.然后将NSOperation对象添加到NSOperationQueue中 4.系统会自动将NSOperationQueue中的NSOperation取出来 5.将取出的NSOperation封装的操作放到一条新线程中执行 NSOperat

使用NSOperation和NSOperationQueue实现多线程编程

使用NSOperation和NSOperationQueue实现多线程编程,实现步骤大致是这样的: 1> 先将需要执行的操作封装到一个NSOperation对象中 2> 然后将NSOperation对象添加到NSOperationQueue中 3> 系统会自动将NSOperation中封装的操作放到一条新线程中执行 回到顶部 一.NSInvocationOperation 1 NSInvocationOperation *operation = [[[NSInvocationOperat

Swift - 多线程实现方式(2) - NSOperation和NSOperationQueue

1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueue) (3)Grand Central Dispath(GCD) 2,本文着重介绍Cocoa NSOperation Cocoa NSOperation不需要关心线程管理和数据同步的事情,可以把精力放在自己需要执行的操作上.相关的类有NSOperation和 NSOperationQueue.其中N

用NSOperation和NSOperationQueue实现多线程编程

1.上一讲简单介绍了NSThread的使用,虽然也可以实现多线程编程,但是需要我们去管理线程的生命周期,还要考虑线程同步.加锁问题,造成一些性能上的开销.我们也可以配合使用NSOperation和NSOperationQueue实现多线程编程,实现步骤大致是这样的: 1> 先将需要执行的操作封装到一个NSOperation对象中 2> 然后将NSOperation对象添加到NSOperationQueue中 3> 系统会自动将NSOperation中封装的操作放到一条新线程中执行 在此过

iOS多线程编程之NSOperation和NSOperationQueue的使用(转自容芳志专栏)

转自由http://blog.csdn.net/totogo2010/ 使用 NSOperation的方式有两种, 一种是用定义好的两个子类: NSInvocationOperation 和 NSBlockOperation. 另一种是继承NSOperation 如果你也熟悉Java,NSOperation就和java.lang.Runnable接口很相似.和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main.相当与ja

NSOperation 和NSOperationQueue使用

示例项目的功能就是用tableview来展示经过滤镜处理的图片.图片会从网络下载,然后添加滤镜,最后展示在tableview中. 下面是应用的示意图: 初始模型 第一次尝试 下载 示例工程 . 注意:所有图片来源于 stock.xchng .一些图片有意的拼错名字,用来测试下载失败的情况. 运行工程,(最终)你会看到应用展示一列图片.试着滚动列表.很痛苦,不是吗? 所有的动作都发生在 ListViewController.swift 中,并且大多数都在 tableView(_:cellForRo

【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例(转载)

(1)GCD实现的同步异步.串行并行. ——同步sync应用场景:用户登录,利用阻塞 ——串行异步应用场景:下载等耗时间的任务 /** * 因为是异步,所以开通了子线程,但是因为是串行队列,所以只需要开通1个子线程(2),它们在子线程中顺序执行.最常用. */ -(void)gcdDemo1{ dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL); for