目录
一、异步分配任务
二、串行队列和并行队列、主队列
三、异步分配任务和串行队列、并行队列的两种组合举例,来验证一下前两部分的理论
其实NSOperation就是对GCD有做了一层OC封装,基本的功能两者都能实现,NSOperation与GCD的最大不同就是可以设置最大并发数和设置任务之间的依赖关系,但平常还是使用GCD多一些。
一、异步分配任务
前一篇我们讲GCD的时候说到了GCD有异步分配任务和同步分配任务之分,但是同步分配任务暂时没有找到它存在的意义,而且还容易造成死锁,那NSOperation这里就没有同步分配任务这么一说,只要我们创建一个任务,添加到队列时就是异步添加的,也就是说使用NSOperation肯定会开辟线程而且不会阻塞当前线程
。
创建一个任务operation:
- target创建法
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
- block创建法
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
// 任务...
}];
二、串行队列和并行队列、主队列
我们知道GCD里分为串行队列和并行队列,但是在NSOperation里则没有那么明显的区分串行队列和并行队列,只要你创建了一个队列它就是并行队列,只不过你把队列的最大并发数设置为1的时候,它就是一个串行队列了。
1、串行队列
// 把队列的最大并发数设置为1,就是一个串行队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
但是要注意在GCD里,系统只会为一个串行队列开辟一个线程来顺序执行串行队列里的任务,但是在NSOperation里,系统会为串行队列也开辟多个线程,但是任务的执行顺序却还是按顺序执行的,因此说NSOperation的执行效率比GCD还高
,下面会有验证。
2、并行队列
// 默认是并行队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
系统会为并行队列也开辟多个线程,来并行执行队列里的任务,执行顺序不一定。
3、主队列
// 主队列
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
回到主线程举例:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 刷新UI或做其它操作...
}];
三、异步分配任务和串行队列、并行队列的两种组合举例,来验证一下前两部分的理论
1、异步分配任务 + 串行队列
我们把5个任务异步地分配到1个串行队列里:
- (void)viewDidLoad {
[super viewDidLoad];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务1");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务2");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务3");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务4");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务5");
NSLog(@"%@", [NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];// 最大并发数设置为1,串行队列
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
}
输出:
任务1
<NSThread: 0x60000173dbc0>{number = 3, name = (null)}
任务2
<NSThread: 0x600001735b00>{number = 4, name = (null)}
任务3
<NSThread: 0x600001734e00>{number = 5, name = (null)}
任务4
<NSThread: 0x600001734e00>{number = 5, name = (null)}
任务5
<NSThread: 0x600001734e00>{number = 5, name = (null)}
可见:
线程是不一样的,开辟了多个,所以说在NSOperation这里,针对串行队列也是开辟多个线程来执行任务的,但是又能保证任务按顺序执行,因此执行效率要比GCD还高些。
2、异步分配任务 + 并行队列
我们把5个任务异步地分配到1个并行队列里:
- (void)viewDidLoad {
[super viewDidLoad];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务1");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务2");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务3");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务4");
NSLog(@"%@", [NSThread currentThread]);
}];
NSBlockOperation *operation5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务5");
NSLog(@"%@", [NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
}
输出:
任务3
任务4
任务1
任务2
<NSThread: 0x600003f80000>{number = 4, name = (null)}
<NSThread: 0x600003f800c0>{number = 3, name = (null)}
<NSThread: 0x600003f84900>{number = 5, name = (null)}
<NSThread: 0x600003f80140>{number = 6, name = (null)}
任务5
<NSThread: 0x600003f800c0>{number = 3, name = (null)}
可见:
系统会为并行队列也开辟多个线程,来并行执行队列里的任务,执行顺序不一定。
网友评论