NSOperation

作者: coma | 来源:发表于2015-11-12 17:46 被阅读146次

    NSOperation的使用

    NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类,使用NSOperation子类的方式有3种

    • NSBlockOperation
         //1. 封装任务
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{      
            NSLog(@"1---%@", [NSThread currentThread]);
        }];
        //2.追加其它任务
        //注意: 在没有队列的情况下, 如果给BlockOperation追加其它任务, 那么其它任务会在子线程中执行
        [op1 addExecutionBlock:^{
            NSLog(@"2---%@", [NSThread currentThread]);
        }];
        [op1 addExecutionBlock:^{
            NSLog(@"3---%@", [NSThread currentThread]);
        }];
        //3.启动任务
        [op1 start];
    
    • 注意:
      默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作,只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作

    • NSInvocationOperation

        //1.封装任务
        NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
        //2.要想执行任务必须调用start
        [op1 start];
        
        NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2) object:nil];
        [op2 start];
    }
    - (void)run
    {
        NSLog(@"%@", [NSThread currentThread]);
    }
    - (void)run2
    {
        NSLog(@"%@", [NSThread currentThread]);
    }
    
    • 自定义NSOperation
      自定义NSOperation的步骤:
      自定义一个继承自NSOperation的子类,并重写- (void)main方法,在里面实现想执行的任务.
      只要将任务添加到队列中, 那么队列在执行自定义任务的时候,就会自动调用main方法
        //1.创建队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
         //2.创建任务
         //自定义任务的好处: 提高代码的复用性
        YFYOperation *op1 = [[YFYOperation alloc] init];
        YFYOperation *op2 = [[YFYOperation alloc] init];
        
         //3.添加任务到队列
        [queue addOperation:op1];
        [queue addOperation:op2];
    
    • 重写- (void)main方法的注意点:
      自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释 放池)
      经常通过- (BOOL)isCancelled方法检测操作是否被取消,对取消做出响应

    NSOperationQueue

    • NSOperationQueue的作用
      NSOperation可以调用start方法来执行任务,但默认是同步执行的,如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
    • NSOperationQueue与NSBlockOperation
        //1.创建队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        //2.创建任务
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"1 == %@", [NSThread currentThread]);
        }];
        NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"2 == %@", [NSThread currentThread]);
        }];
      [queue addOperationWithBlock:^{
            NSLog(@"3 == %@", [NSThread currentThread]);
        }];
    /*如果是使用block来封装任务, 那么有一种更简便的方法,只要利用队列调用addOperationWithBlock:方法, 系统内部会自动封装成一个NSBlockOperation,然后再添加到队列中*/
      // 3.添加任务到队列
        [queue addOperation:op1];
        [queue addOperation:op2];
    
    • NSOperationQueue与 NSInvocationOperation
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
         //2.创建任务
         //只要是自己创建的队列, 就会在子线程中执行,而且默认就是并发执行
        NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
        NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download2) object:nil];
        //3.添加任务到队列中,只要将任务添加到队列中, 队列会自动调用start
        [queue addOperation:op1];
        [queue addOperation:op2];
    - (void)download1
    {
        NSLog(@"1 == %@", [NSThread currentThread]);
    }
    - (void)download2
    {
        NSLog(@"2 == %@", [NSThread currentThread]);
    }
    

    最大并发数

    • 什么是并发数?
      同时执行的任务数,比如,同时开3个线程执行3个任务,并发数就是3

    • 最大并发数的相关方法:
      - (NSInteger)maxConcurrentOperationCount;
      - (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

    • 自己创建的队列默认是并发, 如果设置
      NSOperationQueue *queue = [[NSOperationQueue alloc] init];
      queue.maxConcurrentOperationCount = 1;//就是串行

    • 注意: 不能设置为0, 如果设置为0就不执行任务,
      默认情况下maxConcurrentOperationCount = -1
      在开发中并发数最多尽量不要超过5~6条

    队列的取消、暂停、恢复

    • 只要设置队列的suspended为YES, 那么就会暂停队列中其它任务的执行
      self.queue.suspended = YES;
      也就是说不会再继续执行没有执行到得任务
    • 注意: 设置为暂停之后, 不会立即暂停,会继续执行当前正在执行的任务, 直到当前任务执行完毕, 就不会执行下一个任务了,也就是说, 暂停其实是暂停下一个任务, 而不能暂停当前任务
    • 注意: 暂停是可以恢复的,只要设置队列的suspended为NO, 那么就会恢复队列中其它任务的执行
    • 取消队列中所有的任务的执行
      [self.queue cancelAllOperations];
      取消和暂停一样, 是取消后面的任务, 不能取消当前正在执行的任务
    • 注意: 取消是不可以恢复的

    操作依赖

    • NSOperation之间可以设置依赖来保证执行顺序,比如一定要让操作A执行完后,才能执行操作B,可以这么写
      [operationB addDependency:operationA]; // 操作B依赖于操作A
    • 注意:不能相互依赖,比如A依赖B,B依赖A.
    • 可以在不同queue的NSOperation之间创建依赖关系
        // 1.创建队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];
    
        // 2.创建任务
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"1-------%@", [NSThread currentThread]);
        }];
        NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"2-------%@", [NSThread currentThread]);
        }];
        NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"3-------%@", [NSThread currentThread]);
        }];
        NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"4-------%@", [NSThread currentThread]);
            for (int i = 0; i < 1000; i++) {
                NSLog(@"%i", i);
            }
        }];
        NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"5-------%@", [NSThread currentThread]);
        }];
        // 3.添加依赖
        [op5 addDependency:op1];
        [op5 addDependency:op2];
        [op5 addDependency:op3];
        [op5 addDependency:op4];
        // 4.监听op4什么时候执行完毕
        op4.completionBlock = ^{
            NSLog(@"op4中所有的操作都执行完毕了");
        };
       // 5.添加任务到队列
        [queue addOperation:op1];
        [queue addOperation:op2];
        [queue2 addOperation:op3];
        [queue2 addOperation:op4];
        [queue addOperation:op5];
    

    相关文章

      网友评论

        本文标题:NSOperation

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