多线程 -- NSOperation

  • NSOperation

    • 此类不能直接使用
      • NSInvocationOperation
      • NSBlockOperation
      • 定义一个类继承与它
    • NSInvocationOperation
      • 可以使用start执行操作
      • 在主线程中执行
    • NSBlockOperation
      • 可以使用start执行操作
      • 后期还可以额外的追加操作: addExecutionBlock
      • 第一个任务再主线程中执行, 后面追加的操作在子线程中执行
  • NSOperationQueue

  • NSOperationQueue和GCD对比

    • GCD
      • 并发: 自己创建, 全局
      • 串行: 自己创建, 主队列
    • NSOperationQueue
      • 主队列: mainQueue
        • 永远在主线程中执行
      • 自己创建队列: alloc init
        • 会开启新的线程, 在子线程中执行
    • 如何控制并行和串行
      • maxConcurrentOperationCount = -1 ; 并行
      • 默认就是并行
      • maxConcurrentOperationCount = 1 ; 串行
      • maxConcurrentOperationCount = 0 ; 不会执行
    • 使用步骤:
      • 和GCD一样
      • 1.创建操作(任务)
      • 2.将任务添加到队列中
    • 快速添加任务的方法
      // 只要利用队列调用addOperationWithBlock:方法, 系统内部会自动封装成一个NSBlockOperation \
      然后再添加到队列中
      [queue addOperationWithBlock:^{
        NSLog(@"3 == %@", [NSThread currentThread]);
      }];

       

  • 队列的暂停和恢复以及取消

    • 暂停
      • self.queue.suspended = YES;
      • 注意点:暂停其实是暂停下一个任务, 而不能暂停当前任务
    • 恢复
      • self.queue.suspended = NO;
      • 注意点: 恢复之后会继续执行队列中没有被执行的操作
    • 取消
      • [self.queue cancelAllOperations];
      • 实现原理: 调用所有操作的cancel方法
      • 注意点: 取消其实是取消下一个任务, 而不能取消当前任务
      • 如果自定义操作中做了很多耗时操作, 苹果建议定期检查是否已经取消了
- (void)main
{
    // 耗时操作1
    for (int i = 0; i < 10000; i++) { // 500
        NSLog(@"%i ==== %@", i, [NSThread currentThread]);
    }
    NSLog(@"++++++++++++++++++++++++++++++++++++++");
  //判断是否已经取消了
if (self.isCancelled) { return; } // 耗时操作2 for (int i = 0; i < 10000; i++) { // 500 NSLog(@"%i ==== %@", i, [NSThread currentThread]); } if (self.isCancelled) { return; } NSLog(@"++++++++++++++++++++++++++++++++++++++"); // 耗时操作3 for (int i = 0; i < 10000; i++) { // 500 NSLog(@"%i ==== %@", i, [NSThread currentThread]); } }

 

注: 另一种思路(未求证的) 再循环内部去判断,可以直接终止循环,而不需要等循环完全结束

  • 队列之间的依赖
    • 在操作添加到队列之前, 利用操作调用addDependency, 就快要添加依赖
    • 添加依赖之后, 只有所有依赖的任务都执行完毕, 才会执行当前任务
    • 注意点: 不要相互依赖
    • 特点: 跨队列依赖(GCD默认是不支持)
 // 3.添加依赖
    [op5 addDependency:op1];
    [op5 addDependency:op2];
    [op5 addDependency:op3];
    [op5 addDependency:op4];
  • 操作的监听

    • 只需要利用操作调用completionBlock即可
    • 只要任务执行完毕, 就会回调completionBlock
  • 线程间的通信

    • 将任务添加到自己创建的队列中
    • 再利用mainQueue回到主队列
  • SDWebImage

    • 已经实现内存/磁盘缓存, 并且能够防止重复下载
    • 一般情况会在applicationDidReceiveMemoryWarning方法中取消正在下载的任务
      [[SDWebImageManager sharedManager] cancelAll];
      
    • cleanDisk:
      • 清除已经过期的图片, 并且如果剩余的图片大于了最大的缓存大小, 会继续删除未过期的图片
    • clearDisk:
      • 删除缓存目录中所有的缓存图片 (内部就是删除了整个文件夹, 再重新创建一个)
    • SDWebImage默认的缓存时间是多长:
      • 1星期
    • SDWebImage是如何播放gif图片的
      • 取出gif中的每一帧图片, 重新生成了一张新的可动画的图片
    • 如何判断图片的类型
      • 判断图片的十六进制的前8字节
posted @ 2015-08-20 16:07  Apolla  阅读(156)  评论(0编辑  收藏  举报