多线程之NSOperation和NSOperationQueue
这篇文章里我将不过多的谈及理论知识,这些东西会的自然会,不会的,看多了也是云里雾里。下面我讲更多的用代码+注释的方式来讲如何使用NSOperation和NSOperationQueue。
1、NSOperation。是抽象类,不能够直接使用,而是使用子类NSInvocationOperation和NSBlockOperation来实际执行任务。NSOperation本身和多线程是没有任何关系的,她只是封装了一个代码段和数据去实现一个功能。
1.1、NSInvocationOperation,基于一个对象和selector来创建操作。看下面的代码:
- (void)invocationOperation { NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startOpration) object:nil];
[operation setCompletionBlock:^{
NSLog(@"执行完成,是否主线程:%@", [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[operation start]; //启动任务
[operation cancel]; //取消任务
[operation isExecuting]; //任务是否在执行
[operation isFinished]; //任务是否已经结束
} - (void)startOpration {
NSLog(@"开始执行,是否主线程:%@", [NSThread isMainThread] == ? @"YES" : @"NO");
}
首先是创建了一个operation,并给operation添加了一个需要执行的方法:startOpration。其中Line4中的方法将会在operation执行完成后执行,当然不是必须的,如果需要在operation执行完进行一些操作,可以写上这个方法。
下面是执行的结果:
-- ::19.577 NSOperation[:] 开始执行,是否主线程:YES
-- ::19.577 NSOperation[:] 执行完成,是否主线程:NO
根据上面执行的结果,我们可以发现, startOpration 这个方法是在主线程执行的。至于Line4~Line6是在子线程执行的,则不在今天的讨论内容中,略过。
1.2、NSBlockOperation。相对于NSInvocationOperation,NSBlockOperation则是将selector中需要调用的方法使用Block进行了封装,使用起来更加的方便。关于Block的使用,不明白的同学可以参考我的上一篇博客。
NSBlockOperation对象能够并发的执行一个或多个Block对象,所有相关的Block都执行完成之后,操作才算完成。下面看代码:
- (void)blockOperation {
//创建一个操作
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
//通过addExecutionBlock方法添加Block操作
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
[blockOperation addExecutionBlock:^{
NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == ? @"YES" : @"NO");
}];
//执行操作
[blockOperation start];
//上面的几个Block是并发执行的,将会在不同的线程中执行,
}
下面是执行的结果:
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cad07c30>{number = , name = main},是否主线程:YES
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cae223c0>{number = , name = (null)},是否主线程:NO
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cac0eb60>{number = , name = (null)},是否主线程:NO
-- ::28.586 NSOperation[:] ,<NSThread: 0x7f97cad07c30>{number = , name = main},是否主线程:YES
-- ::28.585 NSOperation[:] ,<NSThread: 0x7f97cad06530>{number = , name = (null)},是否主线程:NO
可以从上面的执行结果中,很容易的发现,程序是并行的执行。而创建的操作,也就是:Line4是在主线程中执行,而其他通过通过 addExecutionBlock 方法添加的Block操作则是在不同的线程中执行。
通过上面的说明,我要总结的是:NSOperation以及子类,只是一个操作,本身无主线程和子线程的区分,可以在任意线程中使用。也就是,在主线程中创建的操作将在主线程中执行,在子线程中创建的操作将在子线程中执行。而实现多线程可以配合NSOperationQueue来实现。下面来介绍NSOperationQueue。
2.NSOperationQueue,是操作队列,它用来管理一组NSOperation对象的执行,会根据需要自动为NSOperation对象开辟适合数量的线程,以完成任务的并行执行。下面上代码:
- (void)operationQueue {
//创建一个任务队列,alloc(new)出来的任务队列将会在子线程中执行,并且是并发执行
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//创建操作NSInvocationOperation
for (int i = ; i < ; i++) {
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startOpration) object:nil];
[queue addOperation:operation];
}
//创建NSBlockOperation操作
for (int i = ; i < ; i++) {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%d,%@,%d", __LINE__, [NSThread currentThread], [NSThread isMainThread]);
}];
//将操作添加到队列中
[queue addOperation:blockOperation];
}
//设置最大并发数,当把最大并发数设置1时,此时队列相当于串行执行。
queue.maxConcurrentOperationCount = ;
//添加依赖关系
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"这是任务1,依赖于任务2");
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"这是任务2");
}];
//添加依赖关系
//添加依赖关系时,注意不能添加互相依赖,如A依赖B,B依赖A
[op1 addDependency:op2];
//添加依赖关系必须在任务添加到队列之前设置
[queue addOperation:op1];
[queue addOperation:op2];
//回到主线程的操作
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"%d,%@,%d", __LINE__, [NSThread currentThread], [NSThread isMainThread]);
}];
}
下面是执行的结果:
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.625 NSOperation[:] 开始执行,是否主线程:NO
-- ::11.626 NSOperation[:] ,<NSThread: 0x7f852bc099f0>{number = , name = (null)},
-- ::11.627 NSOperation[:] ,<NSThread: 0x7f852bf0db10>{number = , name = (null)},
-- ::11.628 NSOperation[:] ,<NSThread: 0x7f852bc46ee0>{number = , name = (null)},
-- ::11.628 NSOperation[:] ,<NSThread: 0x7f852bc4fe00>{number = , name = (null)},
-- ::11.628 NSOperation[:] ,<NSThread: 0x7f852be0a130>{number = , name = (null)},
-- ::11.629 NSOperation[:] 这是任务2
-- ::11.629 NSOperation[:] 这是任务1,依赖于任务2
-- ::11.631 NSOperation[:] ,<NSThread: 0x7f852bd05190>{number = , name = main},
从上面的执行结果中,我们可以得到几个结论:1.首先队列中的任务都是在子线程中执行的;2.队列中的任务是并发执行的。而常用到的添加依赖关系,以及操作完成之后回到主线程的方法在上面的代码中都有体现。
需要说明的是,一旦将operation添加到队列中后,队列就拥有了这个操作,操作将不能从队列中删除,只能取消一个操作,或者取消所有的操作。取消一个操作的方法:
[operation cancel];
取消所有操作的方法:
[queue cancelAllOperations];
如果想要暂停操作的执行可以使用方法: [queue setSuspended:YES]; 来实现。但是暂停不会导致正在执行的操作被暂停,只会阻止队列调度新的操作执行。可以通过方法: [queue setSuspended:NO]; 来继续队列的执行。
3、最后做一个简单的总结。NSInvocationOperation 和 NSBlockOperation的功能是开启一个线程任务,这个线程任务处于子线程和主线程取决于线程任务是在哪个线程中开辟的。这些任务可以使用线程任务队列NSOperationQueue来管理,当new一个队列时,队列所管理的任务都在子线程中执行.当使用[NSOperationQueue mainQueue]时,队列管理的任务在主线程中执行。
以上就是这篇文章的多有内容,如果有不对或者不足的地方,请大家在评论中指出,大家一起讨论。
多线程之NSOperation和NSOperationQueue的更多相关文章
- iOS多线程之NSOperation,NSOperationQueue
使用 NSOperation的方式有两种, 一种是用定义好的两个子类: NSInvocationOperation 和 NSBlockOperation. 另一种是继承NSOperation 如果你也 ...
- iOS多线程之NSOperation和NSOperationQueue的使用
一:NSOperation 两个子类+重写main方法 NSInvocationOperation NSBlockOperation 有个类方法 BlockOprationWith: 还有就是自己个子 ...
- 多线程之NSOperation
关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD
- iOS多线程之NSOperation详解
使用NSOperation和NSOperationQueue进行多线程开发,只要将一个NSOperation(实际开发中需要使用其子类 NSInvocationOperation,NSBlockOpe ...
- iOS-多线程之NSOperation
前言 这篇文章主要讲NSOperation的使用. What 使用NSOperation和NSOperationQueue进行多线程开发类似于线程池,只要将一个NSOperation(实际开发中需要使 ...
- IOS多线程之NSOperation学习总结
NSOperation简介 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 2.NSOperation和NSOperationQu ...
- iOS 多线程之NSOperation篇举例详解
这篇博客是接着总篇iOS GCD NSOperation NSThread等多线程各种举例详解写的一个支篇.总篇也包含了此文的链接.本文讲解的知识点有NSBlockOperationClick,队列, ...
- [转] iOS多线程编程之NSOperation和NSOperationQueue的使用
<iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...
- iOS多线程编程之NSOperation和NSOperationQueue的使用
前一篇 <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是 ...
随机推荐
- 再次讲解js中的回收机制是怎么一回事。
在前几天的一篇闭包文章中我们简单的介绍了一下闭包,但是并没有深入的讲解,因为闭包涉及的知识点比较多,为了能够更好的理解闭包,今天讲解一下关于js中的回收机制. 在初识闭包一文中我说过js中有回收机制这 ...
- Tools - Oracle SQL Developer
Oracle SQL Developer Oracle公司出品的一个免费非开源的用以开发数据库应用程序的图形化工具. 可以浏览数据库对象.运行SQL语句和脚本.编辑和调试PL/SQL语句,也可以创建执 ...
- 15款提高工作效率的 Web 项目管理工具
在今天的快节奏的商业世界里,能够通过计划.组织.和管理资源池以及评估开发资源的模式来管理一个项目,是一个很艰巨的任务. 有很多现成的项目管理软件来帮助减轻项目管理的负担,并且他们几乎覆盖了所有类型的业 ...
- LeetCode——Find the Duplicate Number
Description: Given an array nums containing n + 1 integers where each integer is between 1 and n (in ...
- LeetCode——Jump Game II
Description: Given an array of non-negative integers, you are initially positioned at the first inde ...
- IOS开发UI基础UISlide属性
UISlide属性 • minimumValue : 当值可以改变时,滑块可以滑动到最小位置的值,默认为0.0_slider.minimumValue = 10.0; • maximum ...
- sprint3(第四天)
今天继续完成前台和后台的整合 燃尽图:
- 餐厅到店点餐系统(APP)
MY-HR 成员: 角色分配 学号 博客园 丘惠敏 PM项目经理 201406114203 http://www.cnblogs.com/qiuhuimin/ 郭明茵 用户 201406114204 ...
- 2015年百度之星初赛(1) --- C 序列变换
序列变换 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 三分 --- CSU 1548: Design road
Design road Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1548 Mean: 目的:从(0,0)到 ...