美文网首页
NSOperation的使用

NSOperation的使用

作者: 攻克乃还_ | 来源:发表于2017-12-01 18:01 被阅读13次
  • NSOperation是对GCD的包装
    两个核心概念【队列+操作】

  • NSOperation本身是抽象类,只能只有它的三个子类:
    NSBlockOperation NSInvocationOperation 自定义类继承NSOperation

  • NSOperation要和NSOperationQueue结合使用实现多线程并发

一、NSOperation基本使用

1.1.NSInvocationOperation

    //1.封装操作
    /*
     第一个参数:目标对象
     第二个参数:该操作要调用的方法,最多接受一个参数
     第三个参数:调用方法传递的参数,如果方法不接受参数,那么该值传nil
     */
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                        initWithTarget:self selector:@selector(run) object:nil];
    //2.启动操作
    [operation start];

1.2.NSBlockOperation

    //1.封装操作
    /*
     NSBlockOperation提供了一个类方法,在该类方法中封装操作
     */
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        //在主线程中执行
        NSLog(@"---download1--%@",[NSThread currentThread]);
    }];
    //2.追加操作,追加的操作在子线程中执行
    [operation addExecutionBlock:^{
        NSLog(@"---download2--%@",[NSThread currentThread]);
    }];
    //3.启动执行操作
    [operation start];

1.3.自定义NSOperation

  • 自定义的类继承NSOperation,通过重写内部的main方法实现封装操作
    -(void)main {
        NSLog(@"--main--%@",[NSThread currentThread]);
    }

    //如何使用?
    //1.实例化一个自定义操作对象
    XMGOperation *op = [[XMGOperation alloc]init];
    //2.执行操作
    [op start];

二、 NSOperationQueue基本使用

GCD中的队列:
  • 串行队列:自己创建的/主队列
  • 并发队列:自己创建的/全局并发队列
NSOperation中的两种队列:
  • 主队列:通过mainQueue获得。放到主队列中的任务都将在主线程执行

  • 非主队列:通过alloc init获得。非主队列同时具备了并发和串行的功能,通过设置最大并发数属性来控制任务是并发执行还是串行执行,默认并发

  • 2.1.NSInvocationOperation + NSOperationQueue

- (void)invocation
{
    //1.创建队列
    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.把封装好的操作添加到队列中
    [queue addOperation:op1];//[op1 start]
    [queue addOperation:op2];
}
  • 2.2.NSBlockOperation + NSOperationQueue
- (void)block
{
    //1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //2.封装操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1----%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2----%@",[NSThread currentThread]);
    }];
    [op2 addExecutionBlock:^{
        NSLog(@"3----%@",[NSThread currentThread]);
    }];
    [op2 addExecutionBlock:^{
        NSLog(@"4----%@",[NSThread currentThread]);
    }];
    //3.添加操作到队列中
    [queue addOperation:op1];
    [queue addOperation:op2];

    //补充:简便方法
    [queue addOperationWithBlock:^{
        NSLog(@"5----%@",[NSThread currentThread]);
    }];
}
  • 2.3.自定义NSOperation + NSOperationQueue
-(void)customOperation
{
    //1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //2.封装操作
    //好处:1.信息隐蔽 2.代码复用
    SUNOperation *op1 = [[SUNOperation alloc]init];
    SUNOperation *op2 = [[SUNOperation alloc]init];
    //3.添加操作到队列中
    [queue addOperation:op1];
    [queue addOperation:op2];
}

三、NSOperation其它操作

a.设置最大并发数
  • 控制任务并发和串行
    • 最大并发数等于1,串行;大于1,并行
    • 系统的最大并发数有个默认的值:-1
    • 如果为0,不会执行任何任务
  • 要在任务添加到队列中之前进行设置
    //1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //2.设置最大并发数
    queue.maxConcurrentOperationCount = 2;
b.暂停、恢复、取消
  • 设置暂停和恢复
    • suspended = YES表示暂停,NO表示恢复
    • 暂停表示不继续执行队列中的下一个任务,可以恢复
    if (self.queue.isSuspended) {
        self.queue.suspended = NO;
    }else {
        self.queue.suspended = YES;
    }
c.取消队列里面的所有操作
  • 取消之后,当前正在执行的操作的下一个操作将不再执行,而且永远都不在执行,就像后面的所有任务都从队列里面移除了一样
  • 取消操作不可恢复
  • 苹果官方建议,每当执行完一次耗时操作之后,就查看一下当前队列是否为取消状态,如果是,那么就直接退出,以提高程序的性能

[self.queue cancelAllOperations];

// 自定义NSOperation取消操作
-(void)main
{
    //耗时操作1
    for (int i = 0; i<1000; i++) {
        NSLog(@"任务1-%d--%@",i,[NSThread currentThread]);
    }
    if (self.isCancelled) {
        return;
    }
    //耗时操作2
    for (int i = 0; i<1000; i++) {
        NSLog(@"任务1-%d--%@",i,[NSThread currentThread]);
    }
}

四、NSOperation线程间通信

    // 子线程下载图片
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [queue addOperationWithBlock:^{
        NSLog(@"下载图片--%@",[NSThread currentThread]);
        // 主线程刷新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"刷新UI---%@",[NSThread currentThread]);
        }];
    }];

五、设置操作依赖

- (void)download2
{
    //1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //2.封装操作:下载图片1
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
    }];
    //3.封装操作:下载图片2
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
    }];
    //4.封装操作:合成图片
    NSBlockOperation *combine = [NSBlockOperation blockOperationWithBlock:^{
        // 回到主线程刷新UI
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            NSLog(@"刷新UI---%@",[NSThread currentThread]);
        }];
    }];
    //5.设置操作依赖
    [combine addDependency:op1];
    [combine addDependency:op2];
    //6.添加操作到队列中执行
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:combine];
    }

相关文章

网友评论

      本文标题:NSOperation的使用

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