• NSOperation GCD 对比 (附NSOperation演练)


      项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用。

     NSOperation 与 GCD 的对比

    • GCD

                            将任务(block)添加到队列(串行/并发/主队列),并且指定任务执行的函数(同步/异步)

                            GCD是底层的C语言构成的API

                            iOS 4.0 推出的,针对多核处理器的并发技术

                            在队列中执行的是由 block 构成的任务,这是一个轻量级的数据结构

                            要停止已经加入 queue 的 block 需要写复杂的代码

                            需要通过 Barrier 或者同步任务设置任务之间的依赖关系

                            只能设置队列的优先级

                            高级功能:

                                              一次性 once

                                              延迟操作 after

                                              调度组

    • NSOperation

                            核心概念:把操作(异步)添加到队列(全局的并发队列)

                            OC 框架,更加面向对象,是对 GCD 的封装

                            iOS 2.0 推出的,苹果推出 GCD 之后,对 NSOperation 的底层全部重写

                            Operation作为一个对象,为我们提供了更多的选择

                            可以随时取消已经设定要准备执行的任务,已经执行的除外

                            可以跨队列设置操作的依赖关系

                            可以设置队列中每一个操作的优先级

                            高级功能:

                                              最大操作并发数(GCD不好做)

                                              继续/暂停/全部取消

                   跨队列设置操作的依赖关系

    全局队列
    
    /// 全局操作队列,统一管理所有的异步操作
    
    @property (nonatomic, strong) NSOperationQueue *queue;
    
    - (NSOperationQueue *)queue {
    
        if (_queue == nil) {
    
            _queue = [[NSOperationQueue alloc] init];
    
        }
    
        return _queue;}
    
    最大并发操作数
    
    /// MARK: - 最大并发操作数
    
    - (void)opDemo1 {
    
         // 设置同时并发操作数
    
        self.queue.maxConcurrentOperationCount = 2;
    
        NSLog(@"start");
    
        for (int i = 0; i < 10; ++i) {
    
            NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
    
                [NSThread sleepForTimeInterval:1.0];
    
                NSLog(@"%@ %d", [NSThread currentThread], i);
    
            }];
    
            [self.queue addOperation:op];
    
        }
    
    }
    
    暂停 & 继续
    
    /// MARK: - 暂停 & 继续
    
    - (IBAction)pauseAndResume {
    
        if (self.queue.operationCount == 0) {
    
            NSLog(@"没有操作");
    
            return;
    
        }
    
        // 暂停或者继续
    
        self.queue.suspended = !self.queue.isSuspended;
    
        if (self.queue.isSuspended) {
    
            NSLog(@"暂停 %tu", self.queue.operationCount);
    
        } else {
    
            NSLog(@"继续 %tu", self.queue.operationCount);
    
        }
    
    }
    
    队列挂起,当前"没有完成的操作",是包含在队列的操作数中的
    队列挂起,不会影响已经执行操作的执行状态
    对列一旦被挂起,再添加的操作不会被调度
    取消全部操作
    
    /// MARK: - 取消所有操作
    
    - (IBAction)cancelAll {
    
        if (self.queue.operationCount == 0) {
    
            NSLog(@"没有操作");
    
            return;
    
        }
    
        // 取消对列中的所有操作,同样不会影响到正在执行中的操作!
    
        [self.queue cancelAllOperations];
    
        NSLog(@"取消全部操作 %tu", self.queue.operationCount);
    
    }
    
    1  取消队列中所有的操作
    
    2  不会取消正在执行中的操作
    
    3  不会影响队列的挂起状态
    
    依赖关系
    
    /// MARK: - 依赖关系
    
    - (void)dependency {
    
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
    
            NSLog(@"登录 %@", [NSThread currentThread]);
    
        }];
    
        NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
    
            NSLog(@"付费 %@", [NSThread currentThread]);
    
        }];
    
        NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
    
            NSLog(@"下载 %@", [NSThread currentThread]);
    
        }];
    
        NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
    
            NSLog(@"通知用户 %@", [NSThread currentThread]);
    
        }];
    
        [op2 addDependency:op1];
    
        [op3 addDependency:op2];
    
        [op4 addDependency:op3];
    
        // 注意不要循环依赖
    
    //    [op1 addDependency:op4];
    
        [self.queue addOperations:@[op1, op2, op3] waitUntilFinished:NO];
    
        [[NSOperationQueue mainQueue] addOperation:op4];
    
        NSLog(@"come here");
    
    }
    最怕你一生碌碌无为 还安慰自己平凡可贵
  • 相关阅读:
    大并发服务器开发(实战)
    [亲测有效]Ubuntu20.04安装ROS1和ROS2
    Linux多进程开发(二)
    Linux网络编程(四 )
    统计当前系统的TCP连接状态的种类以及对应的个数
    Linux系统编程入门(一)
    gdb与core 最有效的调试手段之一
    Port was alread in use
    Nginx实现统一端口反向代理多个服务
    Windows Terminal打开管理员权限的PowerShell
  • 原文地址:https://www.cnblogs.com/fakeCoder/p/5093714.html
Copyright © 2020-2023  润新知