NSOperation

2017-09-06  本文已影响0人  锦鲤跃龙

简介

核心概念:将“操作”添加到“队列”

不能直接使用!!! 目的是定义子类共有的属性和方法

NSInvocationOperation
NSBlockOperation

与GCD不同

GCD :将“任务”添加“队列”

调用方法

通过两个子类调用NSInvocationOperation和NSBlockOperation

NSInvocationOperation
//操作
    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downImage:) object:@"invocation"];
    
    //会在当前的线程执行调度方法
    // [op start];
    
   
    //队列
    NSOperationQueue *q = [[NSOperationQueue  alloc]init];
    
    //将操作添加到队列--会自动异步执行调度方法
    [q addOperation:op];

循环添加10个个

//1.队列
     NSOperationQueue *q = [[NSOperationQueue  alloc]init];
    
    
    for (int i = 0; i < 10 ; i++) {
        
        NSInvocationOperation *op  = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downImage:) object:@(i)];
        
        //添加到队列
        [q addOperation:op];
        
    }

执行结果


这里写图片描述
NSBlockOperation
//1.队列
    NSOperationQueue *q = [[NSOperationQueue  alloc]init];
    
    //2.操作
    for (int i = 0; i < 10;i++) {
        
        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"%@----%d",[NSThread currentThread],i);
        }];
        
        //操作添加到队列
        [q addOperation:op];

还有一种更简便的方法

 //1.队列
    NSOperationQueue *q = [[NSOperationQueue  alloc]init];
    
    //2.操作
    for (int i = 0; i < 10;i++) {
        
      [q addOperationWithBlock:^{
           NSLog(@"%@----%d",[NSThread currentThread],i);
      }];
    
    }

多线程直接通信

  [self.opQueue addOperationWithBlock:^{
        NSLog(@"——————%@",[NSThread currentThread]);
        
        //主线程
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            NSLog(@"MainThread %@",[NSThread currentThread]);
        }];
    }];

线程依赖

当某个NSOperation对象依赖于其它NSOperation对象的完成时,就可以通过addDependency方法添加一个或者多个依赖的对象,只有所有依赖的对象都已经完成操作,当前NSOperation对象才会开始执行操作。另外,通过removeDependency方法来删除依赖对象。

[operation2 addDependency:operation1];

依赖关系不局限于相同queue中的NSOperation对象,NSOperation对象会管理自己的依赖, 因此完全可以在不同的queue之间的NSOperation对象创建依赖关系


这里写图片描述

唯一的限制是不能创建环形依赖,比如A依赖B,B依赖A,这是错误的

例子

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];  
  
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){  
    NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);  
}];  
  
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){  
    NSLog(@"执行第2次操作,线程:%@", [NSThread currentThread]);  
}];  
  
[queue addOperation:operation1];  
[queue addOperation:operation2];  

结果为

2017-09-06 14:10:03.561 006--NSOperation[24172:1622100] 执行第2次操作,线程:<NSThread: 0x608000266880>{number = 4, name = (null)}
2017-09-06 14:10:03.561 006--NSOperation[24172:1622099] 执行第1次操作,线程:<NSThread: 0x600000270d80>{number = 3, name = (null)}

可以看到1和2直接顺序不固定

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第2次操作,线程:%@", [NSThread currentThread]);
        sleep(2);
    }];
    
    // operation1依赖于operation2
    [operation1 addDependency:operation2];
    
    [queue addOperation:operation1];
    [queue addOperation:operation2];

结果

2017-09-06 14:12:19.662 006--NSOperation[24236:1626990] 执行第2次操作,线程:<NSThread: 0x600000072b40>{number = 3, name = (null)}
//两秒后执行下面
2017-09-06 14:12:21.737 006--NSOperation[24236:1626994] 执行第1次操作,线程:<NSThread: 0x608000070840>{number = 4, name = (null)}

可以看到再2执行之后才执行1

最大并发数

从iOS 8.0 开始,无论是GCD 还是NSOperation 都会开启很多线程
在 iOS 7.0以前GCD ,一般开5-6;
目前线程多说明:
1. 底层的线程池更大了,能够拿到更多的线程资源了
2. 多线程同时并发的现场数,要求更高了。

 //设置同时最大的并发操作熟练
    self.opQueue.maxConcurrentOperationCount = 2;
    
    /*
     20文件?20线程?
     //WiFi :5-6;
     //流量:  2-3
     
     */
    
    for (int i = 0; i < 20; i++) {
    
        [self.opQueue addOperationWithBlock:^{
            [NSThread sleepForTimeInterval:1.0];
            NSLog(@"%@------%d",[NSThread currentThread],i);
        }];
    }

总结

苹果大力推进iOS开发者使用!

NSOperation 和 GCD对比

  • 将任务(block)添加到队列(串行、并行、主队列、全局队列),并且要指定任务的同步、异步;
  • 线程间的通讯 dispatch_get_main_queue()
  • 提供了一些 NSOperation不具备的功能:
  • 一次执行(单例)
  • 延迟执行
  • 调度组(NSOperation 也可以做到,但是有点麻烦)
  • 将操作[异步执行的任务]添加到 【并发队列】,就会立刻异步执行
  • 提供了一个些GCD实现起来比较麻烦功能
  • 最大并发线程
  • 队列的暂停、继续
  • 取消所有线程
  • 线程依赖(线程A 的执行必须 依赖线程B)(GCD 同步实现!)
上一篇下一篇

猜你喜欢

热点阅读