ObjectiveC的NSOperation多线程类基本使用指南剖析

上传人:仙*** 文档编号:68543051 上传时间:2022-04-03 格式:DOC 页数:11 大小:81KB
收藏 版权申诉 举报 下载
ObjectiveC的NSOperation多线程类基本使用指南剖析_第1页
第1页 / 共11页
ObjectiveC的NSOperation多线程类基本使用指南剖析_第2页
第2页 / 共11页
ObjectiveC的NSOperation多线程类基本使用指南剖析_第3页
第3页 / 共11页
资源描述:

《ObjectiveC的NSOperation多线程类基本使用指南剖析》由会员分享,可在线阅读,更多相关《ObjectiveC的NSOperation多线程类基本使用指南剖析(11页珍藏版)》请在装配图网上搜索。

1、Objective-C的NSOperation多线程类基本使用指南这篇文章主要介绍了 Objective-C 的 NSOperation 多线程类基本使用指南 ,谈到了 Operations 的执行顺序和并发量等设置操作 ,需要的朋友可以参考下NSOperation一、 NSOperation1.简介NSOperation 实例封装了需要执行的操作和执行操作所需的数据, 并且能够以并发或非并发 的方式执行这个操作。NSOperation 本身是抽象基类,因此必须使用它的子类,使用 NSOperation 子类的方式有 2 种:1 Foundation 框 架 提 供 了 两 个 具 体 子 类

2、 直 接 供 我 们 使 用 :NSInvocationOperation 和NSBlockOperation2 自定义子类继承 NSOperation ,实现内部相应的方法2.执行操作NSOperation 调用 start 方法即可开始执行操作, NSOperation 对象默认按同步方式执行 ,也就 是在调用 start 方法的那个线程中直接执行。 NSOperation 对象的 isConcurrent 方法会告诉我 们这个操作相对于调用 start 方法的线程 ,是同步还是异步执行。 isConcurrent 方法默认返回 NO,表示操作与调用线程同步执行3.取消操作operatio

3、n 开始执行之后 , 默认会一直执行操作直到完成,我们也可以调用 cancel 方法中途 取消操作复制代码 代码如下 :operation cancel;4.监听操作的执行如果我们想在 一个 NSOperation 执行完毕后做一些事情,就调 用 NSOperation 的setCompletionBlock 方法来设置想做的事情复制代码 代码如下 :operati on. completi on Block =A() NSLog(执行完毕”);或者复制代码 代码如下 :operati on setCompleti on Block:A() NSLog(执行完毕);二、 NSInvocatio

4、nOperation1.简介基于一个对象和 selector 来创建操作。如果你已经有现有的方法来执行需要的任务,就可以使用这个类2.创建并执行操作复制代码 代码如下 :/ 这个操作是:调用 self 的 run 方法NSInvocationOperation *operation = NSInvocationOperation alloc initWithTarget:selfselector:selector(run) object:nil;/ 开始执行任务 (同步执行 )operation start;三、 NSBlockOperation1.简介能够并发地执行一个或多个 block 对

5、象,所有相关的 block 都执行完之后 ,操作才算完成2.创建并执行操作复制代码 代码如下 :NSBlockOperation *operation = NSBlockOperation blockOperationWithBlock:A()NSLog(执行了一个新的操作,线程:%, NSThread curren tThread);/ 开始执行任务 ( 这里还是同步执行 ) operation start;3.通过 addExecutionBlock 方法添加 block 操作复制代码 代码如下 :NSBIockOperati on Operation = NSBIockOperatio

6、n blockOperatio nWithBlock:A()NSLog(执行第 1 次操作,线程:%, NSThread curren tThread);operati on addExecuti on BIock:A() NSLog( 又执行了 1 个新的操作,线程: %, NSThread curren tThread);operation addExecutionBlock:A() NSLog( 又执行了 1 个新的操作,线程: %, NSThread curren tThread);operation addExecutionBlock:A() NSLog( 又执行了 1 个新的操作,

7、线程: %, NSThread curren tThread);/ 开始执行任务operation start;打印信息如下:2013-02-02 21:38:46.102 thread4602:c07 又 执 行 了1 个 新 的 操 作 , 线 程 :name = (null), num = 1 2013-02-02 21:38:46.102 thread4602:3f03 又执行了 1 个 新的操 作 , 线 程 :name = (null), num = 5 2013-02-02 21:38:46.102thread4602:1b03 执行第 1 次操作,线程: name = (nul

8、l), num = 32013-02-02 21:38:46.102 thread4602:1303 又 执 行 了1 个 新 的 操 作 , 线 程 :name = (null), num = 4可以看出,这 4 个 block 是并发执行的,也就是在不同线程中执行的, num 属性可以看成是 线程的 id四、自定义 NSOperation1. 简介如果 NSInvocationOperation 和 NSBlockOperation 对象不能满足需求 , 你可以直接继承 NSOperation,并添加任何你想要的行为。 继承所需的工作量主要取决于你要实现非并发还是 并发的 NSOperat

9、ion。定义非并发的 NSOperation 要简单许多,只需要重载-(void)main 这个方 法,在这个方法里面执行主任务,并正确地响应取消事件 ; 对于并发 NSOperation, 你必须重写 NSOperation 的多个基本方法进行实现(这里暂时先介绍非并发的NSOperation)2.非并发的 NSOperation比如叫做 DownloadOperation ,用来下载图片1继承 NSOperation,重写 main 方法,执行主任务DownloadOperation.h复制代码 代码如下 :#import protocol DownloadOperationDelegat

10、e;interface DownloadOperation : NSOperation/ 图片的 url 路径property (nonatomic,copy) NSString *imageUrl;/ 代理property (nonatomic,retain) id delegate;- (id)initWithUrl:(NSString *)url delegate:(id)delegate; end复制代码 代码如下 :/ 图片下载的协议protocol DownloadOperationDelegate - (void)loadFinishWithImage:(UIImage *)im

11、age; endDownloadOperation.m复制代码 代码如下 :#import DownloadOperation.himplementation DownloadOperationsynthesize delegate = _delegate;synthesize imageUrl = _imageUrl;/ 初始化- (id)initWithUrl:(NSString *)url delegate:(id)delegate if (self = superinit) self.imageUrl = url; self.delegate = delegate;return sel

12、f;/ 释放内存- (void)dealloc super dealloc;_delegate release;_imageUrl release;/ 执行主任务- (void)main / 新建一个自动释放池,如果是异步执行操作,那么将无法访问到主线程的自动释放 池autoreleasepool / .end 2 正确响应取消事件operation 开始执行之后 ,会一直执行任务直到完成 ,或者显式地取消操作。取消可能发生在 任何时候 ,甚至在 operation 执行之前。尽管 NSOperation 提供了一个方法 ,让应用取消一个操 作,但是识别出取消事件则是我们自己的事情。如果ope

13、ration 直接终止 , 可能无法回收所有已分配的内存或资源。因此 operation 对象需要检测取消事件 ,并优雅地退出执行NSOperation 对象需要定期地调用 isCancelled 方法检测操作是否已经被取消, 如果返回YES 表示已取消),则立即退出执行。不管是自定义 NSOperation 子类,还是使用系统提供的两个具体子类 ,都需要支持取消。isCancelled 方法本身非常轻量 ,可以频繁地调用而不产生大的性能损失以下地方可能需要调用 isCancelled:* 在执行任何实际的工作之前* 在循环的每次迭代过程中,如果每个迭代相对较长可能需要调用多次* 代码中相对比

14、较容易中止操作的任何地方DownloadOperation 的 main 方法实现如下复制代码 代码如下 :- (void)main / 新建一个自动释放池,如果是异步执行操作,那么将无法访问到主线程的自动释放 池autoreleasepool if (self.isCancelled) return;/ 获取图片数据NSURL *url = NSURL URLWithString:self.imageUl;NSData *imageData = NSData dataWithContentsOfURL:url;if (self.isCancelled) url = nil;imageData

15、 = nil;return;/ 初始化图片UIImage *image = UIImage imageWithData:imageData;if (self.isCancelled) image = nil;return;if (self.delegate respondsToSelector:selector(downloadFinishWithImage:) / 把图片数据传回到主线程(NSObject *)self.delegate performSelectorOnMainThread:selector(downloadFinishWithImage:)withObject:image

16、waitUntilDone:NO;NSOperationQueue一、简介一个 NSOperation 对象可以通过调用 start 方法来执行任务,默认是同步执行的。也可以将NSOperation 添加到一个 NSOperationQueue( 操作队列 )中去执行,而且是异步执行的。创建一个操作队列:复制代码 代码如下 :NSOperationQueue *queue = NSOperationQueue alloc init;二、添加 NSOperation 到 NSOperationQueue 中1. 添加一个 operation复制代码 代码如下 :queue addOperatio

17、n:operation;2.添加一组 operation复制代码 代码如下 :queue addOperations:operations waitUntilFinished:NO;3.添加一个 block 形式的 operation复制代码 代码如下 :queue addOperatio nWithBlock:A() NSLog(执行一个新的操作,线程:%, NSThread curre ntThread);NSOperation 添加到 queue 之后,通常短时间内就会得到运行。但是如果存在依赖,或者整个queue 被暂停等原因 ,也可能需要等待。注意: NSOperation 添加到

18、queue 之后 ,绝对不要再修改NSOperation 对象的状态。因为NSOperation 对象可能会在任何时候运行 ,因此改变 NSOperation 对象的依赖或数据会产生不 利的影响。你只能查看 NSOperation 对象的状态 , 比如是否正在运行、等待运行、已经完成 等三、添加 NSOperation 的依赖对象1. 当 某 个 NSOperation 对 象 依 赖 于 其 它 NSOperation 对 象 的 完 成 时 , 就 可 以 通 过addDependency 方法添加一个或者多个依赖的对象,只有所有依赖的对象都已经完成操作, 当前NSOperation 对象

19、才会开始执行操作。另外,通过 removeDependency 方法来删除依赖 对象。复制代码 代码如下 :operation2 addDependency:operation1;依赖关系不局限于相同 queue 中的 NSOperation 对象 ,NSOperation 对象会管理自己的依赖 因此完全可以在不同的 queue 之间的 NSOperation 对象创建依赖关系唯一的限制是不能创建环形依赖,比如A 依赖 B, B 依赖 A,这是错误的2.依赖关系会影响到 NSOperation 对象在 queue 中的执行顺序,看下面的例子: 1 没有设置依赖关系复制代码 代码如下 :NSOp

20、erationQueue *queue = NSOperationQueue alloc init;NSBIockOperati on *operati on1 = NSBIockOperati on blockOperatio nWithBlock:A() NSLog(执行第 1 次操作,线程:%, NSThread curren tThread);NSBIockOperati on *operati on2 = NSBIockOperati on blockOperatio nWithBlock:A() NSLog(执行第 2 次操作,线程:%, NSThread currentThrea

21、d);queue addOperation:operation1;queue addOperation:operation2;打印信息:2013-02-03 00:21:35.024 thread5616:3d13 执 行 第 1 次 操 作 , 线 程 : name = (null), num = 3 2013-02-03 00:21:35.063 thread5616:1303 执行第 2 次操 作,线程: name = (null), num = 4可以看出,默认是按照添加顺序执行的,先执行operation1 ,再执行 operation22 设置了依赖关系复制代码 代码如下 :NSO

22、perationQueue *queue = NSOperationQueue alloc init;NSBIockOperati on *operati on1 = NSBIockOperati on blockOperatio nWithBlock:A() NSLog(执行第 1 次操作,线程: %, NSThread curren tThread);NSBIockOperati on *operati on2 = NSBIockOperati on blockOperatio nWithBlock:A() NSLog(执行第 2 次操作,线程: %, NSThread currentTh

23、read);/ operation1 依赖于 operation2operation1 addDependency:operation2;queue addOperation:operation1;queue addOperation:operation2;打印信息:2013-02-03 00:24:16.260 thread5656:1b03 执 行 第 2 次 操 作 , 线 程 : name = (null), num = 3 2013-02-03 00:24:16.285 thread5656:1303 执行第 1 次操 作,线程: name = (null), num = 4可以看出

24、,先执行 operation2 ,再执行 operation1四、修改 Operations 的执行顺序对于添加到 queue 中的 operations ,它们的执行顺序取决于 2 点:1 .首先看看 NSOperation 是否已经准备好:是否准备好由对象的依赖关系确定2.然后再根据所有 NSOperation 的相对优先级来确定。优先级等级则是 operation 对象本身 的一个属性。默认所有 operation 都拥有“普通”优先级 ,不过可以通过 setQueuePriority:方 法来提升或降低 operation 对象的优先级。 优先级只能应用于相同 queue 中的 ope

25、rations 。如果应用有多个 operationqueue,每个 queue 的优先级等级是互相独立的。因此不同queue中的低优先级操作仍然可能比高优先级操作更早执行。注意: 优先级不能替代依赖关系,优先级只是对已经准备好的operations 确定执行顺序。 先满足依赖关系 ,然后再根据优先级从所有准备好的操作中选择优先级最高的那个执行。五、设置队列的最大并发操作数量队列的最大并发操作数量,意思是队列中最多同时运行几条线程虽然 NSOperationQueue 类设计用于并发执行 Operations, 你也可以强制单个 queue 一次只能 执行一个 Operation。setMax

26、ConcurrentOperationCount:方法可以配置 queue 的最大并发操作 数量。设为1 就表示 queue 每次只能执行一个操作。不过 operation 执行的顺序仍然依赖于 其它因素 ,比如operation 是否准备好和 operation 的优先级等。 因此串行化的 operation queue 并不等同于 GCD 中的串行 dispatch queue复制代码 代码如下 :/ 每次只能执行一个操作queue.maxConcurrentOperationCount = 1;/ 或者这样写queue setMaxConcurrentOperationCount:1;六

27、、取消 Operations一旦添加到 operation queue,queue 就拥有了这个 Operation 对象并且不能被删除 ,唯一能做 的事情是取消。 你可以调用 Operation 对象的 cancel 方法取消单个操作 ,也可以调用 operation queue 的cancelAllOperations 方法取消当前 queue 中的所有操作。复制代码 代码如下 :/ 取消单个操作operation cancel;/ 取消 queue 中所有的操作queue cancelAllOperations;七、等待 Options 完成为了最佳的性能 ,你应该设计你的应用尽可能地异

28、步操作,让应用在 Operation 正在执行时可以去处理其它事情。如果需要在当前线程中处理operation 完成后的结果 ,可以使用NSOperation 的 waitUntilFinished 方法阻塞当前线程,等待 operation 完成。通常我们应该避 免编写这样的代码 ,阻塞当前线程可能是一种简便的解决方案,但是它引入了更多的串行代码限制了整个应用的并发性,同时也降低了用户体验。绝对不要在应用主线程中等待一个Operation,只能在第二或次要线程中等待。阻塞主线程将导致应用无法响应用户事件,应用也将表现为无响应。复制代码 代码如下 :/ 会阻塞当前线程,等到某个 operati

29、on 执行完毕operation waitUntilFinished;除了等待 单个 Operation 完 成,你 也可以 同时等 待 一个 queue 中的所 有操作 ,使 用NSOperationQueue 的 waitUntilAllOperationsAreFinished 方法。注意:在等待一个 queue 时 , 应用的其它线程仍然可以往 queue 中添加 Operation, 因此可能会加长线程的等待时间。复制代码 代码如下 :/ 阻塞当前线程,等待 queue 的所有操作执行完毕queue waitUntilAllOperationsAreFinished;八、暂停和继续 queue如果你想临时暂停 Operations 的执行,可以使用 queue 的 setSuspended:方法暂停 queue。不 过暂停一个 queue 不会导致正在执行的 operation 在任务中途暂停 ,只是简单地阻止调度新 Operation 执行。你可以在响应用户请求时,暂停一个 queue 来暂停等待中的任务。稍后根据 用户的请求,可以再次调用 setSuspended 方法继续 queue 中 operation 的执行复制代码 代码如下 :/ 暂停 queuequeue setSuspended:YES;/ 继续 queuequeue setSuspended:NO;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!