(2)NSOperation

2024-06-17 02:58
文章标签 nsoperation

本文主要是介绍(2)NSOperation,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.简介

NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作。很多执行任务类型的案例都很好的运用了NSOperation,包括网络请求,图像压缩,自然语言处理或者其他很多需要返回处理后数据的、可重复的、结构化的、相对长时间运行的任务。

NSOperation本身是抽象基类,因此必须使用它的子类,使用NSOperation子类的方式有2种:

1> Foundation框架提供了两个具体子类直接供我们使用:NSInvocationOperation和NSBlockOperation

2> 自定义子类继承NSOperation,实现内部相应的方法


2.执行操作

NSOperation调用start方法即可开始执行操作,NSOperation对象默认按同步方式执行,也就是在调用start方法的那个线程中直接执行。NSOperation对象的isConcurrent方法会告诉我们这个操作相对于调用start方法的线程,是同步还是异步执行。isConcurrent方法默认返回NO,表示操作与调用线程同步执行


3.取消操作

operation开始执行之后, 默认会一直执行操作直到完成,我们也可以调用cancel方法中途取消操作。当NSOperation的-cancel状态调用的时候会通过KVO通知isCancelled的keypath来修改isCancelled属性的返回值,NSOperation需要尽快地清理一些内部细节,而后到达一个合适的最终状态。特别的,这个时候isCancelled和isFinished的值将是YES,而isExecuting的值则为NO。

[operation cancel];  


4.监听操作的执行

如果我们想在一个NSOperation执行完毕后做一些事情,就调用NSOperation的setCompletionBlock方法来设置想做的事情。每当一个NSOperation执行完毕,它就会调用它的completionBlock属性一次,这提供了一个非常好的方式让你能在视图控制器(View Controller)里或者模型(Model)里加入自己更多自己的代码逻辑。比如说,你可以在一个网络请求操作的completionBlock来处理操作执行完以后从服务器下载下来的数据。

operation.completionBlock = ^() {  

    NSLog(@"执行完毕");  

};  


或者


[operation setCompletionBlock:^() {  

    NSLog(@"执行完毕");  

}];  

5.NSOPeration、NSInvocationOperation、NSBlockOperation介绍


NSOperation方法和属性的介绍

方法

-(void)start;

-(void)main;

(void)cancel;

-(void)addDependency:(NSOperation *)op;

(void)removeDependency:(NSOperation *)op;

(void)waitUntilFinished


属性:

@property (readonly, getter=isCancelled) BOOL cancelled;

@property (readonly, getter=isExecuting) BOOL executing;

@property (readonly, getter=isFinished) BOOL finished;

@property (readonly, getter=isReady) BOOL ready;

注意:每一个属性对于其他的属性必须是互相独立不同的,也就是同时只可能有一个属性返回YES,从而才能维护一个连续的状态: - isReady: 返回 YES 表示操作已经准备好被执行, 如果返回NO则说明还有其他没有先前的相关步骤没有完成。 - isExecuting: 返回YES表示操作正在执行,反之则没在执行。 - isFinished : 返回YES表示操作执行成功或者被取消了,NSOperationQueue只有当它管理的所有操作的isFinished属性全标为YES以后操作才停止出列,也就是队列停止运行,所以正确实现这个方法对于避免死锁很关键。




@property (readonly, copy) NSArray<NSOperation *> *dependencies;

注意:根据你应用的复杂度不同,将大任务再分成一系列子任务一般都是很有意义的,而你能通过NSOperation的依赖性实现。



typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {

NSOperationQueuePriorityVeryLow = -8L,

NSOperationQueuePriorityLow = -4L,

NSOperationQueuePriorityNormal = 0,

NSOperationQueuePriorityHigh = 4,

NSOperationQueuePriorityVeryHigh = 8

};

@property NSOperationQueuePriority queuePriority;

@property double threadPriority NS_DEPRECATED

注意:不可能所有的操作都是一样重要,通过以下的顺序设置queuePriority属性可以加快或者推迟操作的执行,此外,有些操作还可以指定threadPriority的值,它的取值范围可以从0.0到1.0,1.0代表最高的优先级。鉴于queuePriority属性决定了操作执行的顺序,threadPriority则指定了当操作开始执行以后的CPU计算能力的分配



@property NSQualityOfService qualityOfService


@property (nullable, copy) NSString *name






NSBlockOperation方法和属性介绍

方法:

+ (instancetype)blockOperationWithBlock:(void (^)(void))block;

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

属性:executionBlocks;



NSInvocationOperation方法和属性介绍

方法

- (nullable instancetype)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;

- (instancetype)initWithInvocation:(NSInvocation *)inv

属性

invocation;

result;


例子:

  //NSInvocatioOperation封装操作,使用start在主线程中执行

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

    [operation start];

    

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

    [operation1 start];


输出:test--NSInvocation:<NSThread: 0x7fb2a35081c0>{number = 1, name = main}

           test--1:<NSThread: 0x7fb2a35081c0>{number = 1, name = main}


 //NSInvocatioOperation封装操作,放到队列中,在非主线程中执行

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

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


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

    [queue addOperation:operation2];

    [queue addOperation:operation1];


//队列添加操作

    [queue addOperationWithBlock:^{

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

    }];


输出:

3:<NSThread: 0x7f88e26a2920>{number = 3, name = (null)}

1:<NSThread: 0x7f88e26a2c70>{number = 2, name = (null)}

2:<NSThread: 0x7f88e240e200>{number = 4, name = (null)}



NSOperationQueue方法和属性介绍

NSOperationQueue的作⽤:NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的

如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作

添加操作到NSOperationQueue中,自动执行操作,自动开启线程

方法:

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

(void)addOperations:(NSArray<NSOperation *> *)ops waitUntilFinished:(BOOL)wait  

(void)cancelAllOperations;

- (void)waitUntilAllOperationsAreFinished;

+ (nullable NSOperationQueue *)currentQueue

+ (NSOperationQueue *)mainQueue

(void)addOperationWithBlock:(void (^)(void))block

属性

@property (readonly, copy) NSArray<__kindof NSOperation *> *operations;

@property (readonly) NSUInteger operationCount

@property NSInteger maxConcurrentOperationCount;

@property (getter=isSuspended) BOOL suspended;

@property (nullable, copy) NSString *name

@property NSQualityOfService qualityOfService

@property (nullable, assign /* actually retain */) dispatch_queue_t underlyingQueue

-

这篇关于(2)NSOperation的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1068298

相关文章

iOS开发之NSThread、NSOperation、GCD三者之间的简略比较

1、首先NSThread、NSOperation、GCD这三种方式的发展历程是由早到晚的,因此后者相比较前者而言更加简单易用,即GCD为当前苹果较为推荐的一种方式。 2、NSThread在控制线程优先级方面只能通过“线程休眠sleepForTimeInterval来控制”,且并不精确,依赖于网络状况,并且代码量稍复杂,并且想要传多个参数的时候需要自定义对象 3、NSOperation有一个“线

自定义NSOperation(二)

一、自定义非并发的NSOperation 定义非并发操作比定义并发操作简单得多。 对于非并发操作,您需要做的是执行您的主要任务并适当地响应取消事件; 现有的类基础结构将为您完成其他所有的工作。 对于并发操作,必须使用自定义代码替换某些现有基础架构。 以下部分显示如何实现这两种类型的对象。 1、自定义非并发操作 (1)必须实现main方法 继承NSOperation类,必须实现main方法,

NSOperation官方文档及使用(一)

一、几个概念 thread线程:用于指代码的单独执行路径。 OS X中线程的底层实现基于POSIX线程API。 process进程:用于指运行的可执行文件,其可以包含多个线程。 task任务:用于指代需要执行的工作的抽象概念。 操作:Cocoa中操作是一种面向对象的方式,用于封装我们要异步执行的工作。 操作被设计为与操作队列结合使用或者由它们自己使用。 二、介绍操作如何定义和使用的 1

iOS并行开发:从NSOperation和调度队列开始

原文:iOS Concurrency: Getting Started with NSOperation and Dispatch Queues 在iOS开发中,并行一直被认为是项目里的怪物。它被认为是一个危险的区域,许多开发者尽力去避免的区域。有谣传说多线程代码应尽可能的避免。我同意并行是危险的,不过那只是因为你没有很好地理解。只是因为未知才变得危险。想想人们在生活中危险的行为活动,有

swift之NSOperation的使用

NSOperation是基于GCD实现,封装了一些更为简单实用的功能,因为GCD的线程生命周期是自动管理,所以NSOperation也是自动管理。NSOperation配合NSOperationQueue也可以实现多线程。                实现步骤:                      第1步:将一个操作封装到NSOperation对象中

iOS 小技能:1. 自定义定义NSOperation 2. 任务队列NSOperationQueue的常见方法、最大并发数、操作依赖、队列的取消\暂停\恢复

文章目录 前言I NSOperation简介1.1 NSInvocationOperation1.2 NSBlockOperation II 自定义定义NSOperation2.1 自定义operation的注意事项 III NSOperationQueue3.1队列的基本用法3.1.1)实现多线程的具体步骤3.1.2 正确响应取消事件 3.2 线程间通信3.3 队列的取消、暂停、恢复

【iOS】NSOperation、NSOperationQueue

文章目录 前言一、NSOperation、NSOperationQueue 简介二、NSOperation、NSOperationQueue 操作和操作队列三、NSOperation四、NSOperationQueue五、NSOperationQueue 控制串行执行、并发执行六、 NSOperation 操作依赖七、NSOperation 优先级八、NSOperation、NSOperat

iOS开发多线程NSOperation(四)

NSOperation 可以实现多线程 是一个抽象类 不能直接使用 实现的手段通过该类的子类 NSInvocationOperation NSBlockOperation 实现多线程 NSInvocationOperation 在创建任务时 用一个方法来表示 任务必须放在任务队列中管理 队列保持任务以先进先出的顺序 NSBlockOperation 创建任务时 用一个block来表示

GCD 和 NSOperation 对比 之 面试对话

来源: http://hufeng825.github.io/2013/09/18/ios26/ “你们项目中为什么多线程用GCD 而不用NSOperation呢? 你有没有发现国外的大牛他们多线程都是用NSOperation? 你能告诉我他们这样做的理由吗?” 一下子把我问懵了.我之所以用GCD 是因为GCD用起来比较简单.代码不用分散 比较集中维护度比较高.而且代码的执行效率也

iOS多线程编程技术之NSThread、NSOperation、GCD

iOS有三种多线程编程的技术,分别为: (一)NSThread (二)NSOperation (三)GCD 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。 三种方式的优缺点介绍: 1)NSThread 优点:NSThread比其他两个轻量级 缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销 2