NSOperation
2020-09-17 本文已影响0人
一个半吊子工程师
NSOperation、NSOperationQueue 是苹果提供给我们的一套多线程解决方案。实际上 NSOperation、NSOperationQueue 是基于 GCD 更高一层的封装,完全面向对象。但是比 GCD 更简单易用、代码可读性也更高。
为什么要使用 NSOperation、NSOperationQueue?
1.可添加完成的代码块,在操作完成后执行。
2.添加操作之间的依赖关系,方便的控制执行顺序。
3.设定操作执行的优先级。
4.可以很方便的取消一个操作的执行。
5.使用 KVO 观察对操作执行状态的更改:isExecuteing、isFinished、isCancelled。
一、使用
- 实例化操作
// 实例化操作队列
_queue = [[NSOperationQueue alloc] init];
//NSInvocationOperation
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(opAction) object:nil];
// 如果使用start,会在当前线程启动操作
// [op1 start];
// 1\. 一旦将操作添加到操作队列,操作就会启动
[_queue addOperation:op1];
//NSBlockOperation
#pragma mark 模仿下载网络图像
- (IBAction)operationDemo3:(id)sender {
// 1\. 下载
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载 %@" , [NSThread currentThread]);
}];
// 2\. 滤镜
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"滤镜 %@" , [NSThread currentThread]);
}];
// 3\. 显示
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"更新UI %@" , [NSThread currentThread]);
}];
// 添加操作之间的依赖关系,所谓“依赖”关系,就是等待前一个任务完成后,后一个任务才能启动
// 依赖关系可以跨线程队列实现
// 提示:在指定依赖关系时,注意不要循环依赖,否则不工作。
[op2 addDependency:op1];
[op3 addDependency:op2];
// [op1 addDependency:op3];
[_queue addOperation:op1];
[_queue addOperation:op2];
[[NSOperationQueue mainQueue] addOperation:op3];
}
- 将操作添加到队列NSOperationQueue即可启动多线程执行
[_queue addOperation:op1];
[_queue addOperation:op2];
二、更新UI使用主线程队列
//两方式
[NSOpeationQueue mainQueue] addOperation ^{
};
[[NSOperationQueue mainQueue] addOperation:op3];
三、操作队列
// 控制同时最大并发的线程数量
[_queue setMaxConcurrentOperationCount:2];
提示:此功能仅有NSOperation有!
四、执行先后顺序
//添加操作之间的依赖关系,所谓“依赖”关系,就是等待前一个任务完成后,后一个任务才能启动
//依赖关系可以跨线程队列实现。
//提示:在指定依赖关系时,注意不要循环依赖,否则不工作。
[op2 addDependency:op1];
[op3 addDependency:op2];
[op1 addDependency:op3];
//提示:在指定依赖关系时,注意不要循环依赖,否则不工作。
例:
- (void)OnQueueClick {
// 1.封装操作
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
// operation1.queuePriority = NSOperationQueuePriorityHigh
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i<10; i++) {
NSLog(@"NSBlockOperation------下载图片---%@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.1];
}
}];
// 2.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 2; // 2 ~ 3为宜
// 通过设置依赖来确定operation执行的顺序
[operation2 addDependency:operation3];
[operation3 addDependency:operation1];
// 3.添加操作到队列中(自动执行操作, 自动开启线程)
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperationWithBlock:^{
NSLog(@"NSBlockOperation------下载图片3---%@", [NSThread currentThread]);
}];
// [queue setSuspended:YES];
}