05-多线程(2)

2017-02-08  本文已影响7人  cdd48b9d36e0

0709-NSOperationQueue多图片下载

1、当一个控制器存在多个scrollView时最好把automaticallyAdjustsScrollViewInsets属性的值设为NO(01-单例模式注意)

2、NSOperation(03-nsoperationqueue基本使用)

1. 任务

  1. NSInvocationOperation(很少用)
   - (void)invocationOperation
{
    //这样不加入队列只分配任务就执行,默认就是在主线程
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
    //加入队列就不用star会自动开启
    [op start];
}
  1. NSBlockOperation(很少用)
   - (void)blockOperation
{
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        // 在主线程
        NSLog(@"下载1------%@", [NSThread currentThread]);
    }];
    
    // 添加额外的任务(在子线程执行)
    [op addExecutionBlock:^{
        NSLog(@"下载2------%@", [NSThread currentThread]);
    }];

    [op addExecutionBlock:^{
        NSLog(@"下载3------%@", [NSThread currentThread]);
    }];
    [op addExecutionBlock:^{
        NSLog(@"下载4------%@", [NSThread currentThread]);
    }];
    //加入队列就不用star会自动开启
    [op start];
}
  1. 自定义NSOperation
     //需要执行的任务
      - (void)main
   {
        for (NSInteger i = 0; i<1000; i++) {
        NSLog(@"download1 -%zd-- %@", i, [NSThread currentThread]);
    }
    if (self.isCancelled) return;
    for (NSInteger i = 0; i<1000; i++) {
        NSLog(@"download2 -%zd-- %@", i, [NSThread currentThread]);
    }
    if (self.isCancelled) return;
    for (NSInteger i = 0; i<1000; i++) {
        NSLog(@"download3 -%zd-- %@", i, [NSThread currentThread]);
    }
    if (self.isCancelled) return;
}
    XMGOperation *op5 = [[XMGOperation alloc] init];
    // 添加任务到队列中
    [queue addOperation:op5]; // [op5 start]

2. 队列(NSOperationQueue)

和GCD的联系
  1. GCD的队列类型
  1. NSOperationQueue的队列类型
重要说明
  1. 关键属性maxConcurrentOperationCount(最大并发操作数)(04-nsoperationqueue的最大并发数)
  1. 重要属性suspended(05-nsoperationqueue的挂起和取消)
  1. 有用属性isCancelled(特别是结合自定义队列非常有用)(05-nsoperationqueue的挂起和取消)

鉴于第二点里面注意所说的,一个任务在开启后只会在执行完毕才会结束,那么🍎官方的建议是对一些耗时操作的任务,在多处地方进行isCancelled属性判断,就能够达到当使用[self.queue cancelAllOperations]这个方法时产生“ 中断一个任务的执行”的效果(适用场景:销毁一个控制器时中断他的网络请求,避免产生不必要的崩溃)

  1. 依赖addDependency和监听完成completionBlock
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"download1----%@", [NSThread  currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"download2----%@", [NSThread  currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"download3----%@", [NSThread  currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        for (NSInteger i = 0; i<10; i++) {
            NSLog(@"download4----%@", [NSThread  currentThread]);
        }
    }];
    NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"download5----%@", [NSThread  currentThread]);
    }];
    op5.completionBlock = ^{
        NSLog(@"op5执行完毕---%@", [NSThread currentThread]);
    };
    
    // 设置依赖
    [op3 addDependency:op1];
    [op3 addDependency:op2];
    [op3 addDependency:op4];
    
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue addOperation:op4];
    [queue addOperation:op5];
}

3、小栗子:多图片下载(08-10多图片下载01-显示数据)

知识要点

关于沙盒的三个文件夹
手动实现图片下载的思路(01-多图片下载最终解决方案)
  1. 流程
  1. 注意
    在最后这一步的下载中要注意很多细节问题:下载完成的赋值问题、下载还没有完成前的重复下载问题导、下载失败的问题,其他还有缓存周期、大小的设置
  1. 更完善的做法是在控制器的内存警告方法里清空内存缓存和取消下载任务
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    
    self.images = nil;
    self.operations = nil;
    [self.queue cancelAllOperations];
}
上一篇 下一篇

猜你喜欢

热点阅读