zoukankan      html  css  js  c++  java
  • 多线程 -- 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字节
    本博文由博主根据资料或其他优秀博文整理而成,转载请注明出处,谢谢!
  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    2020软件工程作业02
    2020软件工程作业01
    WEB学习路线2019完整版(附视频教程+网盘下载地址)
    (2018干货系列七)最新大数据学习路线整合
    (2018干货系列六)最新云计算学习路线整合
    (2018干货系列五)最新UI设计学习路线整合
  • 原文地址:https://www.cnblogs.com/Apolla/p/4745508.html
Copyright © 2011-2022 走看看