zoukankan      html  css  js  c++  java
  • iOS开发之NSOperation & NSOperationQueue

    1、简介

    (1) NSOperationQueue(操作队列)是由GCD提供的队列模型的Cocoa抽象,是一套Objective-C的API,为了使并发(多线程)编程变得更加简单,但效率比GCD略低。在实际开发中NSOperationQueue是首选。

    (2) GCD提供了更加底层的控制,而操作队列则在GCD之上实现了一些方便的功能,这些功能对于开发者而言通常是最好最安全的选择。

    队列及操作

    (1)NSOperationQueue有两种不同类型的队列:主队列和自定义队列

    (2)主队列运行在主线程上。

    (3)自定义队列在后台执行(只要自定义队列,都是并发的)。

    (4) NSOperation是不能直接使用的,队列处理的任务是NSOperation的子类:

    (a)NSInvocationOperation

    (b)NSBlockOperation

    2NSOperation的基本使用步骤

    基本使用步骤

    (1) 定义操作队列

    (2) 定义操作

    (3) 将操作添加到队列

    提示:一旦将操作添加到队列,操作就会立即被调度执行

    3NSInvocationOperation(调度操作)

    定义队列:

    self.myQueue = [[NSOperationQueue alloc] init];

    操作调用的方法:

    - (void)operationAction:(id)obj

    {

        NSLog(@"%@ - obj : %@", [NSThread currentThread], obj);

    }

    定义操作并添加到队列:

    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction:) object:@(i)];

    [self.myQueue addOperation:op];

    例如:

    其中myQueue 为:

    @property (nonatomic, strong) NSOperationQueue *myQueue;

    - (void)demoOp2

    {

        // 需要定义一个方法,能够接收一个参数

        // 是用起来不够灵活

        NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demoOp:) object:@"hello op"];

       

    // [self.myQueue addOperation:op];//在子线程运行

       

        [[NSOperationQueue mainQueue] addOperation:op];//在主线程运行

    }

    4NSBlockOperation(块操作)

    定义操作并添加到队列

    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{

        [self operationAction:@"Block Operation"];

    }];

    将操作添加到队列

    [self.myQueue addOperation:op];

    【备注】NSBlockOperation比NSInvocationOperation更加灵活

    例如:

    其中myQueue 为:

    @property (nonatomic, strong) NSOperationQueue *myQueue;

    #pragma mark 设置任务的执行顺序

    - (void)demoOp3

    {

    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(@"更新UI %@", [NSThread currentThread]);

        }];

       

        // 设定执行顺序, Dependency依赖,系统可能会开多个线程,但不会太多

        // 依赖关系是可以跨队列的!

        [op2 addDependency:op1];

        [op3 addDependency:op2];

        [op4 addDependency:op3];

        // GCD是串行队列,异步任务,只会开一个线程

       

        [self.myQueue addOperation:op1];

        [self.myQueue addOperation:op2];

        [self.myQueue addOperation:op3];

        // 所有UI的更新需要在主线程上进行,使op4在主线程执行

        [[NSOperationQueue mainQueue] addOperation:op4];

    }

    5、设置操作的依赖关系

    NSBlockOperation *op1 =

    [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"%@ - 下载图片", [NSThread currentThread]);

    }];

    NSBlockOperation *op2 =

    [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"%@ - 添加图片滤镜", [NSThread currentThread]);

    }];

    NSBlockOperation *op3 =

    [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"%@ - 更新UI", [NSThread currentThread]);

    }];

    // [op1 addDependency:op3];会造成循环依赖

    [op2 addDependency:op1];

    [op3 addDependency:op2];

    [self.myQueue addOperation:op1];

    [self.myQueue addOperation:op2];

    [[NSOperationQueue mainQueue] addOperation:op3];

    提示:利用addDependency可以指定操作之间的彼此依赖关系(执行先后顺序)

    注意:不要出现循环依赖!

    6、设置同时并发的线程数量

    //设置同时并发的线程数量能够有效地降低CPU和内存的开销,这一功能用GCD不容易实现。

    // 新建线程是有开销的

    // 在设定同时并发的最大线程数时,如果前一个线程工作完成,但是还没有销毁,会新建线程

    // 应用场景:网络开发中,下载工作!(线程开销:CPU,MEM)电量!

    // 如果是3G,开3个子线程

    // 如果是WIFI,开6个子线程

    [self.myQueue setMaxConcurrentOperationCount:2];

    for (int i = 0; i < 10; ++i) {

        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{

            [self operationAction:@(i)];

        }];

        [self.myQueue addOperation:op];

    }

  • 相关阅读:
    Core Animation 文档翻译—附录C(KVC扩展)
    Core Animation 文档翻译—附录B(可动画的属性)
    Core Animation 文档翻译—附录A(Layer样貌相关属性动画)
    Core Animation 文档翻译 (第八篇)—提高动画的性能
    Core Animation 文档翻译 (第七篇)—改变Layer的默认动画
    Core Animation 文档翻译 (第六篇)—高级动画技巧
    Core Animation 文档翻译 (第五篇)—构建Layer的层次结构
    用Markdown快速排版一片文章
    Core Animation 文档翻译 (第四篇)—让Layer的content动画起来
    Core Animation 文档翻译(第三篇)—设置Layer对象
  • 原文地址:https://www.cnblogs.com/lifengfneg/p/4774008.html
Copyright © 2011-2022 走看看