美文网首页iOS开发
iOS-多线程:NSOperation、NSOperationQ

iOS-多线程:NSOperation、NSOperationQ

作者: inyourface | 来源:发表于2019-10-14 11:39 被阅读0次

    一、概述

    NSOperation、NSOperationQueue是基于GCD的一层封装。相对于GCD来说,NSOperation、NSOperationQueue可以设置线程依赖、执行顺序、暂停取消执行、设置最大并发数、KVO监听操作状态的改变等操作。

    二、操作、操作队列

    NSOperation、NSOperationQueue是基于GCD的封装,使用方法基本类似,也是存在操作、队列。

    1.操作

    通过使用NSOperation的子类:NSInvocationOperationNSBlockOperation,或者自定义子类来封装要执行的任务。

    2.队列

    NSOperationQueue 对于添加到队列中的操作,首先进入准备就绪的状态,然后开始执行顺序。操作队列通过设置最大并发操作数来控制并发、串行。NSOperationQueue 提供了两种不同类型的队列:主队列和自定义队列。主队列运行在主线程之上,而自定义队列在子线程执行。

    3.使用方法

    NSOperation、NSOperationQueue是搭配使用才能达到多线程的功能。只是用NSOperation是在主线程中同步操作(使用步骤大致与GCD一样)。

        步骤:

        (1)创建操作:把要执行的任务添加到NSOperation对象中

        (2)创建队列:创建NSOperationQueue对象

        (3)操作添加到队列:把NSOperation对象添加到NSOperationQueue对象中

    三、具体的使用方法

    1.NSOperation

    NSOperation是抽象类,只能子类化来使用。有三种方法来封装操作:

        (1)使用子类 NSInvocationOperation

        (2)使用子类 NSBlockOperation

        (3)自定义继承自 NSOperation 的子类,通过实现内部相应的方法来封装操作。

    1.1 子类 NSInvocationOperation

        // 1.创建 NSInvocationOperation 对象

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

        // 2.调用 start 方法开始执行操作

        [op start];

        //3.实现任务

        - (void)doIt{

        //要执行的任务};

    1.2子类 NSBlockOperation

        // 1.创建 NSBlockOperation 对象

        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{

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

            //要执行的任务;

    }

        }];

        // 2.调用 start 方法开始执行操作

        [op start];

         // 3.添加额外的操作

        [op addExecutionBlock:^{

        //可以添加额外的任务

        }];

    1.3自定义继承自 NSOperation 的子类

    自定义继承自 NSOperation 的子类。通过重写 main 或者 start 方法实现自己的 NSOperation 对象。重写main方法我们不需要管理操作的状态属性 isExecuting 和 isFinished。当 main 执行完,这个操作就结束了。

    //1.自定义继承NSOperation的子类

    @interface  AAOperation : NSOperation

    @end

    @implementation AAOperation

    - (void)main {

        //要执行的任务

      }

    //2.在其他类中使用,导入头文件

    - (void)userName:(NSString *)text{

        // 1.创建 AAOperation 对象

        AAOperation*op = [[AAOperationalloc] init];

        // 2.调用 start 方法开始执行操作

        [op start];

    }

    2.创建队列

    NSOperationQueue分为:主队列、自定义队列。自定义队列有串行、并发。

    2.1主队列

    NSOperationQueue *queue = [NSOperationQueue mainQueue];

    2.2自定义队列

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    2.3操作添加到队列

    两种方法:

    (1)- (void)addOperation:(NSOperation *)op;

    需要先创建操作,再将创建好的操作加入到创建好的队列中去。开启新的线程

        // 1.创建队列

        NSOperationQueue *queue = [[NSOperationQueue alloc] init];

        //  创建操作

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

        // 3.添加操作到队列

        [queue addOperation:op1];

    (2)- (void)addOperationWithBlock:(void (^)(void))block;

    无需创建操作,在 block 中添加操作,直接将包含操作的 block 加入到队列中。开启新的线程,并发执行

        // 1.创建队列

        NSOperationQueue *queue = [[NSOperationQueue alloc] init];

        // 2.使用 addOperationWithBlock: 添加操作到队列中

        [queue addOperationWithBlock:^{

        //执行的任务

        }];

    3.串行、并行的控制

    关键属性 maxConcurrentOperationCount最大并发操作数。用来控制一个队列中可以有多少个操作同时参与并发执行。

    maxConcurrentOperationCount 默认情况下为-1,表示不进行限制,可进行并发执行。

    maxConcurrentOperationCount 为1时,串行队列,串行执行。

    maxConcurrentOperationCount 大于1时,并发队列

    四、依赖、优先级、暂停取消、监听

    1.依赖方法:

    - (void)addDependency:(NSOperation *)op; 添加依赖,使当前操作依赖于操作 op 的完成。

    - (void)removeDependency:(NSOperation *)op; 移除依赖,取消当前操作对操作 op 的依赖。

    @property (readonly, copy) NSArray<NSOperation *> *doItArray; 在当前操作开始执行之前完成执行的所有操作对象数组

    2.优先级

    NSOperation 提供了queuePriority(优先级)属性,queuePriority属性适用于同一操作队列中的操作不适用于不同操作队列中的操作

    设置优先级:- (void)setQueuePriority:(NSOperationQueuePriority)p;

    3.取消暂停

     (1)取消队列的所有操作

     - (void)cancelAllOperations;

    注意:也可以调用NSOperation的- (void)cancel方法取消单个操作

     (2)暂停和恢复队列

    - (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列

    - (BOOL)isSuspended; //当前状态

    4.监听

    - (void (^)(void))completionBlock;

    - (void)setCompletionBlock:(void (^)(void))block;

    //操作监听

    op.completionBlock=^{

    NSLog(@"3已经执行完了------%@",[NSThread currentThread]);

    };

    五、线程间通信

    //回到主线程刷新UI

    [[NSOperationQueue mainQueue]addOperationWithBlock:^{

    self.imageView.image=image;NSLog(@"刷新UI---%@",[NSThread currentThread]);

    }];

    相关文章

      网友评论

        本文标题:iOS-多线程:NSOperation、NSOperationQ

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