美文网首页
iOS多线程篇:NSOperation与NSOperationQ

iOS多线程篇:NSOperation与NSOperationQ

作者: younger_times | 来源:发表于2018-02-09 18:24 被阅读52次

概述

配合使用NSOperation(任务)和NSOperationQueue(队列)也可以实现多线程。

  1. 将需要执行的操作封装到一个NSOperation对象中
  2. 然后将NSOperation对象添加到NSOperationQueue中
  3. 系统自动将NSOperationQueue中的NSOperation取出来
  4. 将取出来的NSOperation封装的操作放到一条新的线程中执行

不需要手动开辟线程,系统自动开辟。

NSOperation是一个抽象的类,不具备封装操作的能力,必须使用其子类。

  • NSInvocationOperation
  • NSBlockOperation
  • 自定义子类继承NSOperation

NSInvocationOperation

本质线程在主线程中执行

NSString * url = @"";
NSInvocationOperation *operation = [[NSInvocationOpeartion alloc]initWithTarget:self selector:@selector(todo:) object:url];

[operation start]; //启动

-(void)todo:(NSString *)url{
    //todo
}

NSBlockOperation

blockOperationWithBlock 将在主线程启动,再次为其添加再任务在子线程

// 主线程中添加
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
    //todo
}];

// 添加额外的任务(在子线程执行)
    [operation addExecutionBlock:^{
        NSLog(@"下载2------%@", [NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"下载3------%@", [NSThread currentThread]);
    }];

NSOperationQueue和NSOperation

凡是添加到NSOperationQueue中的任务,系统都自动帮我们开启了一个新的线程。

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSInvocationOperation *ope1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doTask) object:nil];
    NSBlockOperation *ope2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"task 2%@,%d",[NSThread currentThread],[NSThread isMainThread]);
    }];
    [ope2 addExecutionBlock:^{
        NSLog(@"task 3%@,%d",[NSThread currentThread],[NSThread isMainThread]);
    }];
    [ope2 addExecutionBlock:^{
        NSLog(@"task 4%@,%d",[NSThread currentThread],[NSThread isMainThread]);
    }];

    [queue addOperation:ope1];
    [queue addOperation:ope2];

自定义NSOperation子类

//YKOperation
@implementation YKOperation
- (void)main
{
    NSLog(@"task 5%@,%d",[NSThread currentThread],[NSThread isMainThread]);
}
@end
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
YKOperation *ope1 = [[YKOperation alloc] init];
[queue addOperation ope1];

addDependency添加依赖

op2 依赖 op1。 那么只有op1所有任务完成后,op2才运行运行

    NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        sleep(2);
        NSLog(@"task 1%@",[NSThread currentThread]);
    }];
    NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"task 2%@",[NSThread currentThread]);
    }];

//添加依赖
[op2 addDependency:op1];

跨队列依赖

- (void)operationDependency
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        sleep(2);
        NSLog(@"task 1%@",[NSThread currentThread]);
    }];
    NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"task 2%@",[NSThread currentThread]);
    }];
    NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];
    NSOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"task 3%@",[NSThread currentThread]);
    }];
    NSOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        sleep(2);
        NSLog(@"task 4%@",[NSThread currentThread]);
    }];
        //跨队列依赖(让队列1中的任务2等待队列2中的任务4完成后,再执行。用途很广泛)
    [op2 addDependency:op4];
    [queue2 addOperations:@[op3,op4] waitUntilFinished:YES];
    [queue addOperations:@[op1, op2] waitUntilFinished:YES];
}

block监听任务完成

#pragma mark 监听任务执行转态 completionBlock
- (void)detectTaskFinish
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"task 1%@",[NSThread currentThread]);
    }];
    [queue addOperation:op1];
#pragma mark 在completionBlock方法里面添加任务完成之后的事情,例如提醒等
    op1.completionBlock = ^(){
        NSLog(@"任务1执行完毕");
    };
}

NSOperationQueue属性

  • +currentQueue

该方法返回执行当前NSOperation的NSOperationQueue队列。

  • +mainQueue

该方法返回系统主线程的NSOperationQueue队列

  • -(void)addOperation:(NSOperation *)opeartion

将operation添加到NSOperationQueue队列中。

  • -(void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait

将NSArray中包含的所有NSOpeartion添加到NSOperationQueue,如果第二个参数指定为YES,将会阻塞当前线程,直到提交的所有NSOeration执行完成。

  • -operations

只读属性,返回该NSOperationQueue管理的所有NSOperation

  • -operationCount

只读属性 返回数量

  • -cancelAllOperations

取消NSOperationQueue队列中所有正在排队和执行的 NSOperation

  • -waitUntilAllOperationsAreFinished:

阻塞当前线程,直到该NSOperaionQueue中所有排队和执行的NSOperation执行完成才解除阻塞

  • -(NSInteger)maxConcurrentOperationCount:

返回该NSOperationQueue队列最大支持的并发NSOperation数量,其实就是返回该NSOperationQueue队列最大支持的并发NSOperation数量,其实就是返回该NSOperationQueue最大支持多少个并发线程

  • -setMaxConcurrentOperationCount:(NSInteger)count

设置最大支持的并发数,1,为串行队列,>1以上为并发队列

  • -setSuspended:(BOOL)suspend

设置NSOperaionQueue 是否暂定调度正在排队的NSOperation,正在进行的队列不可以被暂停,设置暂停后,程序要先将正在执行的任务执行完,未开始执行的任务将被暂停。

  • -(BOOL)isSuspended

返回NSOperationQueue 是否已暂停调度正在排队的NSOperation

参考文

相关文章

网友评论

      本文标题:iOS多线程篇:NSOperation与NSOperationQ

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