NSOperation是ios基于GCD的封装,实际上会使用GCD也就意味着会使用NSOperation,开发中个人认为使用GCD的效率更高, NSOperation一些常用的属性和方法:
- (void)start; //在当前任务状态和依赖关系合适的情况下,启动NSOperation的main方法任务,需要注意缺省实现只是在当前线程运行。如果需要并发执行,子类必须重写这个方法,并且使 - (BOOL)isConcurrent 方法返回YES
- (void)main; //定义NSOperation的主要任务代码
- (BOOL)isCancelled; //当前任务状态是否已标记为取消
- (void)cancel; //取消当前NSOperation任务,实质是标记isCancelled状态
- (BOOL)isExecuting; //NSOperation任务是否在运行
- (BOOL)isFinished; //NSOperation任务是否已结束
NSOperation其它常用方法,包括依赖关系:
- (BOOL)isReady; //是否能准备运行,这个值和任务的依赖关系相关
- (void)addDependency:(NSOperation *)op; //加上任务的依赖,也就是说依赖的任务都完成后,才能执行当前任务,比如任务A依赖任务B
//[A addDependency:B];只有当任务B执行完之后,A才执行
- (void)removeDependency:(NSOperation *)op; //取消任务的依赖,依赖的任务关系不会自动消除,必须调用该方法
- (NSArray *)dependencies; //得到所有依赖的NSOperation任务
以及用于任务同步:
- (void)waitUntilFinished; //阻塞当前线程,直到该NSOperation结束。可用于线程执行顺序的同步
- (void)setCompletionBlock:(void (^)(void))block; //设置NSOperation结束后运行的block代码,由于NSOperation有可能被取消,所以这个block运行的代码应该和NSOperation的核心任务无关。
NSOperation的子类
NSOperation是抽象类,我们常用的是其子类或者继承自NSOperation的自定义的类,其子类NSInvocationOperation和NSBlockOperation为我们封装了很方便的操作
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self blockOperation];
}
-(void)invocationOpeation
{
//1.创建操作,封装任务
/*
第一个参数:目标对象 self
第二个参数:调用方法的名称
第三个参数:前面方法需要接受的参数 nil
*/
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download2) object:nil];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download3) object:nil];
//2.启动|执行操作
[op1 start];
[op2 start];
[op3 start];
}
-(void)blockOperation
{
//1.创建操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1----%@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2----%@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3----%@",[NSThread currentThread]);
}];
//追加任务
//注意:如果一个操作中的任务数量大于1,那么会开子线程并发执行任务
//注意:不一定是子线程,有可能是主线程
[op3 addExecutionBlock:^{
NSLog(@"4---%@",[NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
NSLog(@"5---%@",[NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
NSLog(@"6---%@",[NSThread currentThread]);
}];
//2.启动
[op1 start];
[op2 start];
[op3 start];
}
-(void)download1
{
NSLog(@"%s----%@",__func__,[NSThread currentThread]);
}
-(void)download2
{
NSLog(@"%s----%@",__func__,[NSThread currentThread]);
}
-(void)download3
{
NSLog(@"%s----%@",__func__,[NSThread currentThread]);
}
@end
NSOperationQueue结合NSOperation的子类的用法
- 1和NSInvocationOperation的使用组合
//1.创建操作,封装任务
/*
第一个参数:目标对象 self
第二个参数:调用方法的名称
第三个参数:前面方法需要接受的参数 nil
*/
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download2) object:nil];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download3) object:nil];
//2.创建队列
/*
GCD:
串行类型:create & 主队列
并发类型:create & 全局并发队列
NSOperation:
主队列: [NSOperationQueue mainQueue] 和GCD中的主队列一样,串行队列
非主队列: [[NSOperationQueue alloc]init] 非常特殊(同时具备并发和串行的功能)
//默认情况下,非主队列是并发队列
*/
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//3.添加操作到队列中
[queue addOperation:op1]; //内部已经调用了[op1 start]
[queue addOperation:op2];
[queue addOperation:op3];
-(void)download1
{
NSLog(@"%s----%@",__func__,[NSThread currentThread]);
}
-(void)download2
{
NSLog(@"%s----%@",__func__,[NSThread currentThread]);
}
-(void)download3
{
NSLog(@"%s----%@",__func__,[NSThread currentThread]);
}
- 2和NSBlockOperation的使用组合
//1.创建操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1----%@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2----%@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3----%@",[NSThread currentThread]);
}];
//追加任务,会增加线程,有可能是子线程,也有可能是在主线程执行
[op2 addExecutionBlock:^{
NSLog(@"4----%@",[NSThread currentThread]);
}];
[op2 addExecutionBlock:^{
NSLog(@"5----%@",[NSThread currentThread]);
}];
[op2 addExecutionBlock:^{
NSLog(@"6----%@",[NSThread currentThread]);
}];
//2.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//3.添加操作到队列
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
//简便方法
//1)创建操作,2)添加操作到队列中
[queue addOperationWithBlock:^{
NSLog(@"7----%@",[NSThread currentThread]);
}];
自定义继承自NSOperation的类
- 必须重写main方法
#import "YSOperation.h"
@implementation YSOperation
//把要执行的任务放这里来,会自动开线程
//1.有利于代码隐蔽
//2.复用性
-(void)main{
NSLog(@"%@----%s",[NSThread currentThread],__func__);
}
@end
//1.封装操作
YSOperation *op1 = [[YSOperation alloc]init];
YSOperation *op2 = [[YSOperation alloc]init];
//2.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//3.添加操作到队列
[queue addOperation:op1];
[queue addOperation:op2];
网友评论