iOS开发

iOS-多线程:NSOperation、NSOperationQ

2019-10-14  本文已影响0人  inyourface

一、概述

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

}];

上一篇 下一篇

猜你喜欢

热点阅读