iOS多线程的初步研究(六)

iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成、运行等管理代码。当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实现多线程。下面先来研究NSOperationNSOperationQueue类的使用。

NSOperation实质是封装了需要并发运行的代码,一些主要接口和NSThread基本相同,可以看做没有线程运行能力的thread类的抽象。参考NSThread,NSOperation的一些相同的接口有:

- (void)start; //在当前任务状态和依赖关系合适的情况下,启动NSOperation的main方法任务,需要注意缺省实现只是在当前线程运行。如果需要并发执行,子类必须重写这个方法,并且使 - (BOOL)isConcurrent 方法返回YES

- (void)main; //定义NSOperation的主要任务代码

- (BOOL)isCancelled; //当前任务状态是否已标记为取消

- (void)cancel; //取消当前NSOperation任务,实质是标记isCancelled状态

- (BOOL)isExecuting; //NSOperation任务是否在运行

- (BOOL)isFinished; //NSOperation任务是否已结束

NSOperation其它常用方法,包括依赖关系:

- (BOOL)isReady; //是否能准备运行,这个值和任务的依赖关系相关

- (void)addDependency:(NSOperation *)op; //加上任务的依赖,也就是说依赖的任务都完成后,才能执行当前任务

- (void)removeDependency:(NSOperation *)op; //取消任务的依赖,依赖的任务关系不会自动消除,必须调用该方法

- (NSArray *)dependencies; //得到所有依赖的NSOperation任务

以及用于任务同步:

- (void)waitUntilFinished; //阻塞当前线程,直到该NSOperation结束。可用于线程执行顺序的同步

- (void)setCompletionBlock:(void (^)(void))block; //设置NSOperation结束后运行的block代码,由于NSOperation有可能被取消,所以这个block运行的代码应该和NSOperation的核心任务无关。

除了继承NSOperation来实现并发代码,通常更简便的办法是使用它的两个子类NSInvocationOperationNSBlockOperation,然后加入到NSOperationQueue执行队列中去运行。部分示例代码如下:

NSInvocationOperation *opA = [[NSInvocationOperationalloc] initWithTarget:self selector:@selector(operate) object:nil];

NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{

        [self operate];

    }];

- (void)operate

{

  //thread loop

  while (condition)

  {

    //....

  }

}

NSOperationQueue *queue = [[NSOperationQueuealloc] init];

queue.maxConcurrentOperationCount = 2; //设置最大并发执行数,如果为1则同时只有一个并发任务在运行,可控制顺序执行关系

[queue addOperation:opA]; //加入到执行队列中,如果isReady则开始执行

[queue addOperation:opB]; //同上,需要注意这时opA和opB是在并发运行

[queue waitUntilAllOperationsAreFinished]; //当前线程等待,直到opA和opB都执行结束

如果要求opB在opA执行完成后才开始执行,需要加上依赖关系即可:

[opB addDependency:opA];

当然也可以使用同步方法waitUntilFinished,在前面的例子中加入:

NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{

   [opA waitUntilFinished]; //opB线程等待直到opA执行结束(正常结束或被取消)

        [self operate];

    }];

建立依赖关系或等待关系,一定要出现避免循环依赖或循环等待,否则就会造成线程死锁。

最后看看NSOperationQueue的其它常用方法:

- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait; //批量加入执行operation,wait标志是否当前线程等到所有operation结束

- (void)addOperationWithBlock:(void (^)(void))block; //相当于加入一个NSBlockOperation执行任务

- (NSArray *)operations; //返回已加入执行operation的数组,当某个operation结束后会自动从这个数组清除

- (NSUInteger)operationCount //返回已加入执行operation的数目

- (void)setSuspended:(BOOL)b; //是否暂停将要执行的operation,但不会暂停已开始的operation

- (BOOL)isSuspended; //返回暂停标志

- (void)cancelAllOperations; //取消所有operation的执行,实质是调用各个operation的cancel方法

+ (id)currentQueue; //返回当前NSOperationQueue,如果当前线程不是在NSOperationQueue上运行则返回nil

+ (id)mainQueue; //返回主线程的NSOperationQueue,缺省总是有一个queue

 
 
分类: ios
标签: ios多线程

iOS多线程的初步研究(六)的更多相关文章

  1. iOS多线程的初步研究3

    iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...

  2. iOS多线程的初步研究1

    iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...

  3. iOS多线程的初步研究

    iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...

  4. iOS多线程的初步研究(一)-- NSThread

    对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...

  5. iOS多线程的初步研究(六)-- NSOperation

    iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...

  6. iOS多线程的初步研究(三)-- NSRunLoop

    弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run loop可以用于处理异步事件, ...

  7. iOS多线程的初步研究(九)-- dispatch源

    dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...

  8. iOS多线程的初步研究(七)-- dispatch对象

    谈起iOS的dispatch(正式称谓是Grand Central Dispatch或GCD),不得不说这又是iOS(包括MacOSX)平台的创新,优缺点这里不讨论,只有当你使用时才能真正体会到.我们 ...

  9. iOS多线程的初步研究(五)-- 如何让NSURLConnection在子线程中运行

    可以有两个办法让NSURLConnection在子线程中运行,即将NSURLConnection加入到run loop或者NSOperationQueue中去运行. 前面提到可以将NSTimer手动加 ...

随机推荐

  1. AngularJS应用开发思维之3:依赖注入

    找不到的API? AngularJS提供了一些功能的封装,但是当你试图通过全局对象angular去 访问这些功能时,却发现与以往遇到的库大不相同. $http 比如,在jQuery中,我们知道它的AP ...

  2. cocos2d 游戏开发实战

    文章转自:http://uliweb.clkg.org/tutorial/read/40 6   cocos2d 游戏开发实战 6.1   创建cocos2d项目 6.2   cocos2d v3 & ...

  3. WCF消息交换模式之双工通讯(Duplex)

    WCF消息交换模式之双工通讯(Duplex) 双工通讯Duplex具有以下特点: 1它可以在处理完请求之后,通过请求客户端中的回调进行响应操作 2.消息交换过程中,服务端和客户端角色会发生调换 3.服 ...

  4. 【转】关于“ORA-01653: 表 SYS.AUD$ 无法通过 128 (在表空间 SYSTEM 中) 扩展”的错误

    SQL*Plus: Release 11.1.0.6.0 - Production on 星期一 5月 17 18:31:08 2010 Copyright (c) 1982, 2007, Oracl ...

  5. 一步一步写算法(之n!中末尾零的个数统计)

    原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...

  6. SQL点滴13—收集SQLServer线程等待信息

    原文:SQL点滴13-收集SQLServer线程等待信息 要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信 ...

  7. 用批处理文件自动备份文件及文件夹,并自动删除n天前的文件

    原文:用批处理文件自动备份文件及文件夹,并自动删除n天前的文件 ---恢复内容开始--- 下是备份的批处理,添加到"计划任务"中,设定时间自动运行 复制代码 代码如下:@echo ...

  8. 大约ActionContext.getContext()使用体验

    这是我在另一个人的博客看了,原来博客的时间长一点.我把它简化了一下,运营商,以方便它看起来. 为了避免与Servlet API耦合在一起,方便Action类做单元測试,Struts 2对HttpSer ...

  9. Oracle自主事务处理

    --当一个子程序调用另外一个子程序时,事务提交或回滚都将影响两个子程序 --为防止一个子程序的事务影响其他子程序,可以将这个子程序标记为自主事务处理 --这样自主事务成为一个独立的事务处理,不影响其他 ...

  10. IP地址规划和设计方法

    IP地址规划和设计方法 无类域间路由技术需要在提高 IP 地址利用率和减少主干路由器负荷两个方面取得平衡 网络地址转换 NAT 最主要的应用是专用网,虚拟专用网,以及 ISP 为拨号用户 提供的服务 ...