NSOperation

简介

  • 概念

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

  • 特点

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

  • 子类

    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 同步实现!)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值