本文主要是介绍(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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!