ios NSoperation
来源:互联网 发布:比特币交易网免费源码 编辑:程序博客网 时间:2024/05/16 16:21
文章目录 一、NSOperation简介 二、NSOperation和NSOperationQueue的基本使用 1、创建任务 2、创建队列 3、将任务加入到队列中 三、控制串行执行和并行执行的关键 四、操作依赖 五、一些其他方法
一、NSoperation的简介
NSOperation是苹果提供给我们的一套多线程解决方案。实际上NSOperation是基于GCD更高一层的封装,但是比GCD更简单易用、代码可读性也更高。
NSoperation 总共有两个子类 : NSInvocationOperation 和 NSBlockOperation。
NSOperation需要配合NSOperationQueue来实现多线程。因为默认情况下,NSOperation单独使用时系统同步执行操作,并没有开辟新线程的能力,只有配合NSOperationQueue才能实现异步执行。
因为NSOperation是基于GCD的,那么使用起来也和GCD差不多,其中,NSOperation相当于GCD中的任务,而NSOperationQueue则相当于GCD中的队列。NSOperation实现多线程的使用步骤分为三步:
1、创建任务:先将需要执行的操作封装到一个NSOperation对象中。
2、创建队列:创建NSOperationQueue对象。
3、将任务加入到队列中:然后将NSOperation对象添加到NSOperationQueue中。
之后呢,系统就会自动将NSOperationQueue中的NSOperation取出来,在新线程中执行操作。
注意和GCD 类比学习 : Operation 相当于任务、操作队列就和GCD其实是同个意思。总归来说,NSOperation 比GCD 更有自主性!例如: 可以通过继承重写main方法自定义任务、可暂停任务、可恢复任务、可通过KVO监Operation是否完成或取消,可设置任务权重优先执行任务、可设置等待等
下面我们来学习下NSOperation和NSOperationQueue的基本使用。
二、NSOperation和NSOperationQueue的基本使用
NSOperation是个抽象类,并不能封装任务。我们只有使用它的子类来封装任务。我们有三种方式来封装任务:
1、使用 NSInvocationOperation
2、使用 NSBlockOperation
3、自定义子类继承NSoperation,并重写main方法
1、在不使用NSOperationQueue,单独使用NSOperation的情况下系统同步执行操作,下面我们学习以下任务的三种创建方式。
1 ) 使用 NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil]; // 调用start 方法执行操作 [operation start];//其中run方法的定义如下- (void)run{ NSLog(@"NSInvocationOperation -> 当前线程:%@", [NSThread currentThread]); }
运行结果 :
说明 :从中可以看到,在没有使用队列(NSOperationQueue),单独使用NSInvocationOperation的情况下,NSInvocationOperation在主线程执行操作,并没有开启新线程。
.
.
.
2 ) 使用 NSBlockOperation
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"NSBlockOperation -> 当前线程:%@", [NSThread currentThread]); }]; // NSBlockOperation 提供 addExecutionBlock,可通过这个进行添加额外的操作,这些额外操作在有可能在主线程中执行,也有可能会开启子线程去执行。 [blockOperation addExecutionBlock:^{ NSLog(@"NSBlockOperation 额外操作任务1:%@", [NSThread currentThread]); }]; [blockOperation addExecutionBlock:^{ NSLog(@"NSBlockOperation 额外操作任务2:%@", [NSThread currentThread]); }]; [blockOperation addExecutionBlock:^{ NSLog(@"NSBlockOperation 额外操作任务3:%@", [NSThread currentThread]); }]; [blockOperation start];
运行结果 :
说明 :
<1> 在没有使用NSOperationQueue、单独使用NSBlockOperation的情况下,NSBlockOperation也是在主线程执行操作,并没有开启新线程
<2> NSBlockOperation 提供 addExecutionBlock,可通过这个进行添加额外的操作,这些额外操作在有可能在主线程中执行,也有可能会开启子线程去执行
.
.
.
3 ) 自定义子类继承NSoperation,并重写main方法
先定义一个继承自NSOperation的子类,重写main方法
CustomOperation.h
#import <Foundation/Foundation.h>@interface CustomOperation : NSOperation@end
CustomOperation.m
#import "CustomOperation.h" @implementation CustomOperation- (void)main{ for (int i = 0; i < 2; i++) { NSLog(@"定义继承自NSOperation的子类封装任务:%@",[NSThread currentThread]); }}@end
导入头文件 CustomOperation.h
CustomOperation *customOperation = [[CustomOperation alloc]init]; [customOperation start];
运行结果 :
说明 : 在没有使用NSOperationQueue、单独使用自定义子类的情况下,是在主线程执行操作,并没有开启新线程。
2、创建队列
和GCD中的并发队列、串行队列略有不同的是:NSOperationQueue一共有两种队列:主队列、其他队列。其中其他队列同时包含了串行、并发功能。下边是主队列、其他队列的基本创建方法和特点。
主队列
凡是添加到主队列的任务,必然是放在主线程中执行
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
其它队列
添加到这种队列中的任务(NSOperation),就会自动放到子线程中执行,同时包含了:串行、并发功能
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
3、将任务添加到队列中去
// 1、 创建 队列NSOperationQueue *queue = [[NSOperationQueue alloc]init];// 2、定义任务NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 2; i++) { NSLog(@"NSBlockOperation任务:%@",[NSThread currentThread]); } }];// 3、 将任务添加到队列中[queue addOperation:invocationOperation];[queue addOperation:blockOperation];
运行结果 :
说明 :NSInvocationOperation和NSOperationQueue结合后能够开启新线程,进行并发执行NSBlockOperation和NSOperationQueue也能够开启新线程,进行并发执行。
当然,你也可以无需先创建任务,可以在block中添加任务,直接将block中的人添加到队列中。
[queue addOperationWithBlock:^{ for (int i = 0; i < 2; i++) { NSLog(@"任务:%@",[NSThread currentThread]); } }];
运行结果 :
.
.
.
三、控制串行执行和并行执行的关键
之前我们说过,NSOperationQueue创建的其他队列同时具有串行、并发功能,上边我们演示了并发功能,那么他的串行功能是如何实现的?
这里有个关键参数maxConcurrentOperationCount,这个官方的解释是如下
The maximum number of queued operations that can execute at the same time.
中文可译为 : 可以同时执行的队列操作的最大数量
maxConcurrentOperationCount 默认值为-1,表示不进行限制,默认为并发执行
当 maxConcurrentOperationCount = 1,串行执行任务
当maxConcurrentOperationCount大于1时,进行并发执行,当然这个值不应超过系统限制,即使自己设置一个很大的值,系统也会自动调整。
注意 : 这个参数主要控制队列是串行执行任务还是并行执行任务,具体开启的线程数交由系统控制。
具体看下面一个例子 :
// 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //queue.maxConcurrentOperationCount = -1; queue.maxConcurrentOperationCount = 1; // 添加操作 [queue addOperationWithBlock:^{ NSLog(@"1-----%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"2-----%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"3-----%@", [NSThread currentThread]); }];
当 maxConcurrentOperationCount = -1 时控制台输出
当 maxConcurrentOperationCount = 1 时控制台输出
可以看出:当最大并发数为1时,任务是按顺序串行执行的。当最大并发数为2时,任务是并发执行的。而且开启线程数量是由系统决定的,不需要我们来管理。这样看来,是不是比GCD还要简单了许多?
四、设置操作依赖
NSOperation和NSOperationQueue最吸引人的地方是它能添加操作之间的依赖关系。比如说有A、B两个操作,其中A执行完操作,B才能执行操作,那么就需要让B依赖于A。具体如下:
- (void)addOperationDepedency{ // 1、 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2、 创建任务 NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"1-----%@", [NSThread currentThread]); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"2-----%@", [NSThread currentThread]); }]; //让op2 依赖于 op1,则先执行op1,在执行op2 [op2 addDependency:op1]; // 3、 将任务添加到队列中 [queue addOperation:op2]; [queue addOperation:op1];}//添加操作依赖
运行结果 :
.
.
.
五、一些其他方法
NSOperation提供的方法,可取消单个操作
- (void)cancel;
NSOperationQueue提供的方法,可以取消队列的所有操作
- (void)cancelAllOperations;
可设置任务的暂停和恢复,YES代表暂停队列,NO代表恢复队列
- (void)setSuspended:(BOOL)b;
判断暂停状态
- (BOOL)isSuspended;
注意: 这里的暂停和取消并不代表可以将当前的操作立即取消,而是当当前的操作执行完毕之后不再执行新的操作。 暂停和取消的区别就在于:暂停操作之后还可以恢复操作,继续向下执行;而取消操作之后,所有的操作就清空了,无法再接着执行剩下的操作。
相关链接 :
本文Demo传送门
GCD和NSOperation的区别和选用
- iOS NSOperation
- iOS NSOperation
- iOS NSOperation
- ios NSoperation
- ios-NSOperation
- iOS NSOperation
- IOS 多线程 NSOperation
- iOS多线程之NSOperation
- iOS多线程之NSOperation
- iOS线程 ----NSOperation
- 【iOS】多线程NSOperation
- iOS 之 NSOperation,NSOperationQueue
- iOS NSOperation使用方法简介
- iOS多线程之NSOperation
- ios多线程之NSOperation
- IOS多线程之NSOperation
- 【iOS开发】NSOperation
- IOS--UI--NSOperation
- zookeeper—分布式锁实现(笔记)
- IOS多线程开发其实很简单
- bzoj4917 [ lydsy6月月赛A题 ]
- opencv 采用多边形进行区域筛选
- android音乐播放器之歌词下载、处理、开始、同步
- ios NSoperation
- IE8,9中将event传到其他作用域会失效
- SpringMVC如何访问JSP
- python nonzero()函数的用法
- HTML5新增标签汇总
- Python股票处理之三_实时监测
- 在VirtualBox中安装Oracle的相关配置
- Git 清理无效的远程追踪分支
- Ai 科技大本营