NSOperation

2020-09-17  本文已影响0人  一个半吊子工程师

NSOperation、NSOperationQueue 是苹果提供给我们的一套多线程解决方案。实际上 NSOperation、NSOperationQueue 是基于 GCD 更高一层的封装,完全面向对象。但是比 GCD 更简单易用、代码可读性也更高。

为什么要使用 NSOperation、NSOperationQueue?

1.可添加完成的代码块,在操作完成后执行。
2.添加操作之间的依赖关系,方便的控制执行顺序。
3.设定操作执行的优先级。
4.可以很方便的取消一个操作的执行。
5.使用 KVO 观察对操作执行状态的更改:isExecuteing、isFinished、isCancelled。

一、使用

  1. 实例化操作
// 实例化操作队列
_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]; 
}
  1. 将操作添加到队列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];
}
上一篇下一篇

猜你喜欢

热点阅读