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");

}
最怕你一生碌碌无为 还安慰自己平凡可贵
原文地址:https://www.cnblogs.com/fakeCoder/p/5093714.html