美文网首页
NSOperation的使用

NSOperation的使用

作者: CoderLWG | 来源:发表于2018-02-05 11:46 被阅读7次

    1.NSOperation总结

    NSOperaton 是苹果大力推荐的"并发"技术!
    NSOperation 的核心概念:将"操作" 添加到 "队列"
    GCD 将"任务"添加到 "队列"
    NSOperation 类 是一个抽象类
    特点:
    -不能直接使用!
    目的:
    -定义子类共有的属性和方法
    子类:
    NSInvocationOperation
    NSBlockOperation
    自定义子类继承NSOperation,实现内部相应的方法


    GCD & NSOperation 对比
    GCD 在 iOS 4.0 推出,主要针对多核处理器做了优化的并发技术,是C语言的

    • 将"任务"[block]添加到 队列[串行/并发/主队列/全局队列] ,并且指定执行任务的函数[同步/异步]
    • 线程间的通讯 dispatch_get_main_queue()
    • 提供了一些 NSOperation 不具备的功能
      • 一次执行
      • 延迟执行
      • 调度组(在op中也可以做到,有点麻烦)

    NSOperation 在 iOS 2.0 推出的,苹果推出 GCD以后,对NSOperation 底层做了重写!

    • 将操作[异步执行的任务] 添加到队列[并发队列],就会立刻异步执行
    • 线程间的通讯 mainQueue
    • 提供了一些GCD 实现起来比较困难的功能
      • 最大并发线程
      • 队列的暂停/继续
      • 取消所有操作
      • 指定操作之间的依赖关系(GCD 用同步来实现)

    2.NSInvocationOperation使用

    /*
    开启多个线程  不会顺序执行
     NSOperation 本质上是对 GCD  的面向对象的封装!
     - 队列:本质上 就是GCD的并发队列
     - 操作:异步执行任务
    
    */
    //1.队列
        NSOperationQueue * q = [[NSOperationQueue alloc]init];
        for (int i = 0; i < 10; i++) {
             NSInvocationOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@(i)];
            
            //将操作添加到队列 - 会自动异步执行调度方法
            [q addOperation:op];
        }
    
    image.png

    3.NSBlockOperation使用

    //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);
            }];
        }
    

    4.全局队列

    //先懒加载全局队列
    -(NSOperationQueue *)opQueue
    {
        if (!_opQueue) {
            _opQueue = [[NSOperationQueue alloc]init];
        }
        return _opQueue;
    }
    
    -(void)demo{
     //直接添加任务
        for (int i = 0; i < 10; i++) {
            [self.opQueue addOperationWithBlock:^{
                NSLog(@"%@ --- %d",[NSThread currentThread],i);
            }];
        }
        
        //block operation
        NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
                NSLog(@"BLOCK %@ --- %d",[NSThread currentThread],100);
        }];
        [self.opQueue addOperation:op1];
        
        //invocation operation
        NSInvocationOperation * op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImage:) object:@"invocation"];
        [self.opQueue addOperation:op2];
    }
    

    5.线程间的通信

    -(void)demo{
        [self.opQueue addOperationWithBlock:^{
            NSLog(@"耗时操作  %@",[NSThread currentThread]);
            //主线程更新 UI
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                NSLog(@"UI操作  --- %@",[NSThread currentThread]);
            }];
            
        }];
    }
    

    6.设置最大并发数

    从 iOS 8.0 开始,无论使用 GCD还是 NSOperation ,都会开启很多线程
    在 iOS 7.0 以前,GCD 通常只会开启 5 6条线程!
    目前线程多了说明:
    1.底层的现场池更大了,能够拿到的线程资源多了!
    2.多控制同时并发的现场数,要求就更高了!
    设置同时最大的并发操作数量
    WIFI: 5 至 6
    流量 : 2 到 3

    可以看出,maxConcurrentOperationCount不设置的时候,最大并发数有22个
    -(void)demo{
       self.opQueue.maxConcurrentOperationCount = 2;
     //添加操作进队列
        for (int i = 0;i < 20; i++) {
            [self.opQueue addOperationWithBlock:^{
                [NSThread sleepForTimeInterval:1.0];
                NSLog(@"%@---%d",[NSThread currentThread],i);
            }];
        } 
    }
    
    
    image.png

    7.队列的取消、暂停、恢复

    取消队列的所有操作
    - (void)cancelAllOperations;
    提示:也可以调用NSOperation的- (void)cancel方法取消单个操作
    
    暂停和恢复队列
    - (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列
    - (BOOL)isSuspended;
    

    8.操作依赖

    NSOperation之间可以设置依赖来保证执行顺序
    比如一定要让操作A执行完后,才能执行操作B,可以这么写
    [operationB addDependency:operationA]; // 操作B依赖于操作A
    可以在不同queue的NSOperation之间创建依赖关系
    注意:不能相互依赖
    比如A依赖B,B依赖A
    

    相关文章

      网友评论

          本文标题:NSOperation的使用

          本文链接:https://www.haomeiwen.com/subject/jwubzxtx.html