多线程-NSOperationQueue

  1. NSOperationQueue与GCD对比

    1. GCD是c的API执行效率更高。
    2. NSOperationQueue可以设置最大并发数,优先级,依赖关系来调整任务执行顺序。
    3. NSOperationQueue是OC的对象,可以进行KVO监听是否是在执行是否已经完成,或者取消。
    4. NSOperationQueue可以取消,挂起,恢复还没有进行的操作。
    5. 如果GCD能解决问题,我们尽量用GCD。如果GCD解决不了问题,我们就用NSOperationQueue。
  2. NSOperationQueue的简单使用

  NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
    
    //1.
    [operationQueue addOperationWithBlock:^{
        NSLog(@"curThread = %@",[NSThread currentThread]);
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"mainOperationQueue");
        }];
    }];
    
    //2.
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"curThread = %@",[NSThread currentThread]);
    }];
    [operationQueue addOperation:blockOperation];
    
    //3.
    NSInvocationOperation *invocationOpeartion = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo1:) object:@"invocationOperation"];
    [operationQueue addOperation:invocationOpeartion];
    
  1. NSOperationQueue区别于GCD的API

    1. 可以控制最大并发数

      1. 创建异步并发队列与异步串行队列
      2. 代码
       NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
          //控制最大并发数,如果不写相当于异步并发队列。如果写1相当于异步串行队列。如果写其他数字相当于异步并发队列
          operationQueue.maxConcurrentOperationCount = 1;
          for (int i = 0; i < 10; i++) {
              [operationQueue addOperationWithBlock:^{
                  NSLog(@"curThread = %@, i = %d",[NSThread currentThread],i);
              }];
          }
      
    2. 可以添加依赖关系

      1. 可以添加复杂依赖关系
      2. 代码
        operationQueue = [[NSOperationQueue alloc] init];
          
      
          NSBlockOperation *block1 = [NSBlockOperation blockOperationWithBlock:^{
              NSLog(@"1");
          }];
          
          NSBlockOperation *block2 = [NSBlockOperation blockOperationWithBlock:^{
               NSLog(@"2");
          }];
          
          NSBlockOperation *block3 = [NSBlockOperation blockOperationWithBlock:^{
               NSLog(@"3");
          }];
          
          [block1 addDependency:block3];
          [block2 addDependency:block3];
          
          [operationQueue addOperation:block1];
          [operationQueue addOperation:block2];
          [operationQueue addOperation:block3];
      
      1. 设置任务的优先级
        NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
          
          NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
              NSLog(@"curThread = %@, 任务1",[NSThread currentThread]);
          }];
          
          NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
              NSLog(@"curThread = %@, 任务2",[NSThread currentThread]);
          }];
          
          NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
              NSLog(@"curThread = %@, 任务3",[NSThread currentThread]);
          }];
          
          [blockOperation1 setQueuePriority:NSOperationQueuePriorityLow];
          [blockOperation1 setQueuePriority:NSOperationQueuePriorityNormal];
          [blockOperation1 setQueuePriority:NSOperationQueuePriorityHigh];
          
          [operationQueue addOperation:blockOperation1];
          [operationQueue addOperation:blockOperation2];
          [operationQueue addOperation:blockOperation3];
      
      1. KVO
      - (void)viewDidLoad {
          [super viewDidLoad];
          
          NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
          
          blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
              sleep(3.0);
              NSLog(@"curThread = %@, 任务3",[NSThread currentThread]);
          }];
          [operationQueue addOperation:blockOperation3];
          
          [blockOperation3 addObserver:self forKeyPath:@"finished" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
      }
      - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
          if ([keyPath isEqualToString:@"finished"] && object == blockOperation3) {
              NSLog(@"change = %@",change);
          }
      }
      
      1. 取消,挂起,恢复操作
      - (void)viewDidLoad {
          [super viewDidLoad];
          
          operationQueue = [[NSOperationQueue alloc] init];
          operationQueue.maxConcurrentOperationCount = 2;
          for (int i = 0; i < 100; i++) {
              [operationQueue addOperationWithBlock:^{
                  sleep(1.0);
                  NSLog(@"i = %d",i);
              }];
          }
      }
      - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
          //1. 取消所有还没有执行的操作(取消后不可以恢复)
          [operationQueue cancelAllOperations];
          
          //2. 暂停任务和恢复任务
          if (operationQueue.suspended) {
              operationQueue.suspended = NO;
          }else{
              operationQueue.suspended = YES;
          }
      }
      

猜你喜欢

转载自blog.csdn.net/qq_17190231/article/details/83243949
今日推荐