iOS多线程的初步研究(六)
iOS多线程的初步研究(六)
iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成、运行等管理代码。当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实现多线程。下面先来研究NSOperation和NSOperationQueue类的使用。
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来实现并发代码,通常更简便的办法是使用它的两个子类NSInvocationOperation或NSBlockOperation,然后加入到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多线程的初步研究3
iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...
- iOS多线程的初步研究1
iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...
- iOS多线程的初步研究
iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...
- iOS多线程的初步研究(一)-- NSThread
对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...
- iOS多线程的初步研究(六)-- NSOperation
iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...
- iOS多线程的初步研究(三)-- NSRunLoop
弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run loop可以用于处理异步事件, ...
- iOS多线程的初步研究(九)-- dispatch源
dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...
- iOS多线程的初步研究(七)-- dispatch对象
谈起iOS的dispatch(正式称谓是Grand Central Dispatch或GCD),不得不说这又是iOS(包括MacOSX)平台的创新,优缺点这里不讨论,只有当你使用时才能真正体会到.我们 ...
- iOS多线程的初步研究(五)-- 如何让NSURLConnection在子线程中运行
可以有两个办法让NSURLConnection在子线程中运行,即将NSURLConnection加入到run loop或者NSOperationQueue中去运行. 前面提到可以将NSTimer手动加 ...
随机推荐
- POJ1719- Shooting Contest(二分图最大匹配)
题目链接 题意:给定一个矩阵,每列有两个白点,其它都是黑点,如今要求每列选一个白点,使得每一行至少包括一个白点被选中 思路:利用白点所在的位置用行指向列建图,用行去匹配列,最大匹配数假设不等于行数的话 ...
- SSAS系列——【03】多维数据(多维数据集对象)
原文:SSAS系列--[03]多维数据(多维数据集对象) 1.什么是Cube? 简单 Cube 对象由基本信息.维度和度量值组组成. 基本信息包括多维数据集的名称.多维数据集的默认度量值.数据源和存储 ...
- [C#][ASP.net] 透过WebBrowser 取得AJAX 后的网页
原文[C#][ASP.net] 透过WebBrowser 取得AJAX 后的网页 今天 Shih-Min 问我说,假设网页一开始是AJAX 会载入一些资料,但是透过WebClient 去抓 抓到都是J ...
- C# winform调用WebBrowser经典怪问题总结
原文:C# winform调用WebBrowser经典怪问题总结 最近一直研究网页数据采集,单单采集数据,其实HtmlAgilityPack就足够了. 对HtmlAgilityPack感兴趣的可以到这 ...
- WPF应用程序支持多国语言解决方案
原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...
- CORS(跨域资源共享)跨域问题及解决
当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin.肯 ...
- selenium2入门 用testNG对百度首页输入框进行测试 (三)
如果还没有安装testNG的亲,可以点击http://www.cnblogs.com/milanmi/p/4346580.html查看安装过程. 这节主要是对百度首页的输入框进行输入测试. packa ...
- 增加 Java 有几个好习惯表现
以下是一些参考网络资源中的摘要Java编程在一些地方尽可能做. 1. 尝试使用单个例如在合适的场合 使用单例可以减轻负荷的负担,缩短加载时间.提高装载效率,但并不是所有的地方都适合一个案例.简单的说, ...
- Rails当你运行一个数据库回滚错误:ActiveRecord::IrreversibleMigration exception
最近rails3.2在更改数据库表字段,然后要回滚取消,但在运行rake db:rollback命令,错误: rake aborted! An error has occurred, all late ...
- 【本·伍德Lua专栏】补充的基础06:简单的错误处理
昨天遇到另外一位独立游戏开发人员,所以多聊了一会,然后-然后就没有看书了.(小若:借口!借口! ) 今天来聊聊错误处理吧.只是毕竟这仅仅是前面的章节.书上的内容似乎有点一笔带过的味道. 没关系,简单更 ...