免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1438 | 回复: 0
打印 上一主题 下一主题

[iOS] IOS中级篇 —— 多线程 - GCD [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-23 14:13 |只看该作者 |倒序浏览
本帖最后由 船头尺 于 2015-06-23 14:16 编辑

GCD 是c语言的框架,不需要手动管理内存

是一个面向任务   不是面向线程,不需要管理线程的生命周期

GCD 任务/队列 执行函数
任务:Block  任务都封闭在Block中。  —— 线程执行

队列:存放任务    FIFO (先进先出的原则)
        GCD中的队列:
                                  串行队列:想要任务按顺序执行
//    创建一个串行队列
    dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
                                  并发队列:想要任务并发执行(同时执行)
//    创建一个并发队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
两个特殊队列
          主队列:主队列中存放的任务最终会交给主线程来执行。
//    获取主队列  不需要创建
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
          全局并发队列:也是并发队列 没有任何区别。 平常开发用非常多。 (不需要管理 程序需要开多少条线程。 会按照当前的设备来自动开线程         
//    获取全局并发队列  不需要创建
//    long identifier  ios8之前 传线程优先级 DISPATCH_QUEUE_PRIORITY_DEFAULT   ios8以后传0 可以兼容之前的版本
//    <#unsigned long flags#> 保留接口 还未用  传 0
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);

执行函数: 将队列中的任务放到线程中执行
                    同步执行函数:不具备开启新线程的能力。任务中会在当前线程执行。
//      同步
    dispatch_sync(concurrentQueue, ^{
        NSLog(@"下载图片2“);
    });
同步函数 + 并发队列 和 + 串行队列 效果是一样的

                    异步执行函数:具备开启新线程能力。 是否开启线程不一定。 与队列有关
//    执行函数
//      异步执行
//      dispatch_queue_t queue 队列
//      ^(void)block    任务
    dispatch_async(serialQueue, ^{
        NSLog(@"下载图片”);
    });

GCD的作用:
     1>将任务添加到队列中
     2>用执行函数执行任务中的任务
2个执行函数 * 3个队列

同步函数例子
  1. // 同步函数 + 串行队列
  2. 2 // 不会开启新线程,任务是在当前线程执行.
  3. 3 // 如果当前线程是子线程的话,就是在子线程执行
  4. 4 // 任务是按顺序执行的
  5. 5 -(void)test1
  6. 6 {
  7. 7     dispatch_queue_t serialQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
  8. 8     // 同步函数
  9. 9     dispatch_sync(serialQueue, ^{
  10. 10         // 任务
  11. 11         NSLog(@"下载图片1%@",[NSThread currentThread]);
  12. 12     });
  13. 13     // 同步函数
  14. 14     dispatch_sync(serialQueue, ^{
  15. 15         // 任务
  16. 16         NSLog(@"下载图片2%@",[NSThread currentThread]);
  17. 17     });
  18. 18     // 同步函数
  19. 19     dispatch_sync(serialQueue, ^{
  20. 20         // 任务
  21. 21         NSLog(@"下载图片3%@",[NSThread currentThread]);
  22. 22     });
  23. 23 }
  24. 24  
  25. 25 // 同步函数 + 全局并发队列
  26. 26 // 不会开启新线程,在当前线程执行
  27. 27 // 如果当前线程是子线程的话,就是在子线程执行
  28. 28 // 任务按顺序执行
  29. 29 - (void)test2
  30. 30 {
  31. 31     dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  32. 32     dispatch_sync(queue, ^{
  33. 33         NSLog(@"下载图片1%@",[NSThread currentThread]);
  34. 34     });
  35. 35     dispatch_sync(queue, ^{
  36. 36         NSLog(@"下载图片2%@",[NSThread currentThread]);
  37. 37     });
  38. 38     dispatch_sync(queue, ^{
  39. 39         NSLog(@"下载图片3%@",[NSThread currentThread]);
  40. 40     });
  41. 41 }
  42. 42 // 对于同步函数 + 串行队列 和 +并发队列 执行效果是一样的.
  43. 43 // 同步函数 +主队列
  44. 44 // 主队列中的任务都会交给主线程来执行.
  45. 45 // 主线程中的任务和主队列中的任务相互等待,无法执行完毕
  46. 46 - (void)test3
  47. 47 {
  48. 48     dispatch_sync(dispatch_get_main_queue(), ^{
  49. 49         NSLog(@"下载图片1%@",[NSThread currentThread]);
  50. 50     });
  51. 51     dispatch_sync(dispatch_get_main_queue(), ^{
  52. 52         NSLog(@"下载图片2%@",[NSThread currentThread]);
  53. 53     });
  54. 54     dispatch_sync(dispatch_get_main_queue(), ^{
  55. 55         NSLog(@"下载图片3%@",[NSThread currentThread]);
  56. 56     });
  57. 57     NSLog(@"test3End%@",[NSThread currentThread]);
  58. 58
  59. 59 }
复制代码
异步函数例子
  1. // 异步函数 + 主队列
  2. 2     // 不会开启新线程
  3. 3     // 任务按顺序执行
  4. 4     // 不会卡死主线程
  5. 5     dispatch_async(dispatch_get_main_queue(), ^{
  6. 6
  7. 7         NSLog(@"下载图片1%@", [NSThread currentThread]);
  8. 8     });
  9. 9     // 异步函数 + 主队列
  10. 10     dispatch_async(dispatch_get_main_queue(), ^{
  11. 11         NSLog(@"下载图片2%@", [NSThread currentThread]);
  12. 12     });
  13. 13     // 异步函数 + 主队列
  14. 14     dispatch_async(dispatch_get_main_queue(), ^{
  15. 15         NSLog(@"下载图片3%@", [NSThread currentThread]);
  16. 16     });
  17. 17  
  18. 18 // 异步函数 + 串行队列
  19. 19 // 开启一条新线程.
  20. 20 // 一个队列对应一条线程.每一条线程中的任务都是按顺序执行-- 串行执行.
  21. 21 // 如果创建了多个串行队列,会开启多条线程.
  22. 22 - (void)test1
  23. 23 {
  24. 24     dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
  25. 25     dispatch_queue_t queue1 = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
  26. 26     dispatch_async(queue, ^{
  27. 27         NSLog(@"下载图片1%@", [NSThread currentThread]);
  28. 28     });
  29. 29     dispatch_async(queue1, ^{
  30. 30         NSLog(@"下载图片2%@", [NSThread currentThread]);
  31. 31     });
  32. 32
  33. 33     dispatch_async(queue1, ^{
  34. 34         NSLog(@"下载图片3%@", [NSThread currentThread]);
  35. 35     });
  36. 36
  37. 37     dispatch_async(queue, ^{
  38. 38         NSLog(@"下载图片4%@", [NSThread currentThread]);
  39. 39     });
  40. 40 }
  41. 41  
  42. 42 // 异步函数 + 全局并发队列
  43. 43 // 开启一条线程,在子线程中执行任务
  44. 44 // 根据任务数量,开启多条线程.
  45. 45 // GCD自动帮我们开启一定数量的线程.
  46. 46 - (void)test2
  47. 47 {
  48. 48     dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  49. 49     // 异步函数 + 全局并发队列
  50. 50     dispatch_async(queue, ^{
  51. 51         NSLog(@"下载图片1%@",[NSThread currentThread]);
  52. 52     });
  53. 53     // 异步函数 + 全局并发队列
  54. 54     dispatch_async(queue, ^{
  55. 55         NSLog(@"下载图片2%@",[NSThread currentThread]);
  56. 56     });
  57. 57 }
  58. 58  
  59. 59     // 一次性代码,只会执行一次,能够保证线程安全的.
  60. 60     // 线程第一次执行完任务之后,其他线程就不会再进来了.
  61. 61     static dispatch_once_t onceToken;
  62. 62     dispatch_once(&onceToken, ^{
  63. 63         NSLog(@"%@",[NSThread currentThread]);
  64. 64         NSLog(@"一次性代码,只执行一次%@",string);
  65. 65     });
  66. 66  
  67. 67    //队列组的使用
  68. 68 -(void)groupTest
  69. 69 {
  70. 70     __block UIImage *image1,*image2;
  71. 71     // 创建一个队列组
  72. 72     dispatch_group_t group = dispatch_group_create();
  73. 73     // 将我们需要执行的任务放在队列中里面
  74. 74     // 异步的方法
  75. 75     dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
  76. 76         // 任务1
  77. 77         NSLog(@"renwu 1");
  78. 78         image1 = [self downloadImageWithUrlString:@"http://e.hiphotos.baidu.com/zhidao/pic/item/203fb80e7bec54e722c5454ebb389b504fc26ab0.jpg"];
  79. 79     });
  80. 80     // 再往队列组中添加一个任务
  81. 81     dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
  82. 82         // 任务2
  83. 83         NSLog(@"renwu 2");
  84. 84         image2 = [self downloadImageWithUrlString:@"http://www.cnwan.com.cn/uploads/allimg/2011-07/01002414-1-10j14.jpg"];   
  85. 85     });
  86. 86    // 队列组中的任务都执行完毕以后,会发送一个通知,执行下面的方法
  87. 87     dispatch_group_notify(group, dispatch_get_main_queue(), ^{
  88. 88         // 队列组中的任务执行完毕之后的操作
  89. 89         NSLog(@"renwu over");
  90. 90        // 合并图片
  91. 91         self.imageView.image = [self BingImageWith:image1 :image2];
  92. 92     });
  93. 93 }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP