美文网首页
NSOperation

NSOperation

作者: AntKing | 来源:发表于2017-04-28 23:01 被阅读0次

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


相关文章

网友评论

      本文标题:NSOperation

      本文链接:https://www.haomeiwen.com/subject/twgazttx.html