NSOperation

来源:互联网 发布:矢量软件哪个好 编辑:程序博客网 时间:2024/05/17 02:08

简介

  • 概念

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

  • 特点

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

  • 子类

    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对比

  • GCD 在iOS 4.0 推出,主要多核处理器优化的并发技术,是C语言的

    • 将任务(block)添加到队列(串行、并行、主队列、全局队列),并且要指定任务的同步、异步;
    • 线程间的通讯 dispatch_get_main_queue()
    • 提供了一些 NSOperation不具备的功能:
      • 一次执行(单例)
      • 延迟执行
      • 调度组(NSOperation 也可以做到,但是有点麻烦)
  • NSOperation 在iOS 2.0;苹果推出了GCD之后,对NSOperation 进行了重写

    • 将操作[异步执行的任务]添加到 【并发队列】,就会立刻异步执行
    • 提供了一个些GCD实现起来比较麻烦功能
      • 最大并发线程
      • 队列的暂停、继续
      • 取消所有线程
      • 线程依赖(线程A 的执行必须 依赖线程B)(GCD 同步实现!)