(2)NSOperation

来源:互联网 发布:淘宝新店如何刷单 编辑:程序博客网 时间:2024/06/08 16:03

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

-

0 0
原创粉丝点击