多线程之NSOperation

作者: 冷漠叻荭颜 | 来源:发表于2015-04-20 00:56 被阅读2864次

    NSOperation介绍

    • NSOperation

      1. 是 OC 语言中基于 GCD 的面向对象的封装。
      2. 使用起来比GCD更加简单(面向对象)。
      3. 提供了一些用GCD不好实现的功能。
      4. 苹果推荐使用,使用NSOperation不用关心线程以及线程的生命周期。
    • NSOperation的使用

      1. 使用NSOperation处理多线程时,就是将“操作”添加到队列中。
      2. NSOperation是一个抽象类,不能直接使用(方法没有实现),约束子类都具有共同的属性和方法。
      3. NSOperation的子类:NSInvocationOperationNSBlockOperation自定义NSOperation
      4. 通过NSOperationQueue可以创建并发队列,获取主队列,获取当前队列。
    NSInvocationOperation的使用 NSBlockOperation的使用 监听操作完成,回调函数
    • 线程间通讯
      • 主队列,添加到主队列的操作,最终都执行在主线程上。通过NSOperationQueue的mainQueue获取主队列。
      • 通过NSOperationQueue的currentQueue获取当前操作所在的队列。
    线程间通讯
    • GCD和NSOperation的对比
      1. GCD
        • GCD是iOS4.0推出的,主要针对多核CPU做了优化,是C语言的技术。
        • GCD是将任务(block)添加到队列(串行/并行/全局/主队列),并且以同步/异步的方式执行任务的函数。
        • GCD提供给了一些NSOperation不具备的功能:①一次性执行;②延迟执行;③调度组。
      2. NSOperation
        • NSOperation是iOS2.0推出的,iOS4.0之后重写了NSOperation。
        • NSOperation将操作(异步的任务)添加到队列(并发队列),就会执行指定操作的函数。
        • NSOperation里提供的方便的操作:①最大并发数;②队列的暂停/继续;③取消所有的操作;④指定操作之间的依赖关系(GCD可以用同步实现)。

    NSOperation中的方便的使用

    • 最大并发数
      1. 不设置队列的最大并发数:循环把操作添加到队列中,会创建很多线程,线程数越多说明线程池更大了。线程数多并不一定是好事儿,线程越多越耗资源,分配线程的时间也就越多,所以使用线程的时候要合适最好。
      2. 设置队列的最大并发数:循环把操作添加到队列中,会先去线程池中去取空闲的线程,如果没有就创建线程,然后把操作交给从线程池中取出的线程执行,执行完成后,把线程再放回线程池中,重复前面的步骤直到所有的操作都执行完。
    设置最大并发数
    • 暂停/继续/取消/等待
      1. 暂停:设置暂停后,会等待正在执行的任务执行完成后,暂停后续的任务,继续就是对暂停取反。
      2. 取消:清除队列中的任务,取消所有操作,会设置当前队列中所有的操作的cancelled属性为YES,会立即取消所有操作,但是不会立即清空所有操作,而是过一会儿才清空所有操作。
      3. 等待:等待队列中的操作都执行完毕,会阻塞。
    // 暂停
    @property (getter=isSuspended) BOOL suspended;
    // 取消
    - (void)cancelAllOperations;
    // 等待
    - (void)waitUntilAllOperationsAreFinished;
    
    • 依赖关系
      1. 两个操作之间的顺序叫做依赖关系
      2. 用这个方法addDependency:设置操作之间的依赖关系,然后把操作添加到队列中,此时因为设置好了依赖关系,添加顺序就可以随意。
      3. 依赖关系可以跨操作队列,操作不再同一个队列中,依赖关系也是存在的。
    依赖关系

    相关文章

      网友评论

      • 小凡凡520:good mark
      • 一声雷:我感觉这和star方法没什么关系,应该是依赖的操作必须要加到队列中吧,我试了下把两个操作加到主队列中,问题就解决了。
      • 一声雷:- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
        {
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"111%@",[NSThread currentThread]);
        }];
        NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"222%@",[NSThread currentThread]);
        }];

        [op1 addDependency:op2];
        [op2 start];
        [op1 start];
        }
        冷漠叻荭颜:@一声雷 If the operation is currently executing or is not ready to execute, this method throws an NSInvalidArgumentException exception. 详见 - (void)start 方法说明
      • 一声雷:很好,谢谢,我想请教下:在同一条线程(如主线程)中执行A,B两个操作,操作B依赖操作A,如果先执行B,再执行A,那么就回造成卡死的现象。那么我先执行A,再执行B,怎么也报错??
        (ps:我这两个操作没有放到队列中)
        冷漠叻荭颜:@一声雷 可以贴下代码吗
      • 1cfd35193e59:总结的很好,谢谢

      本文标题:多线程之NSOperation

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