船头尺 发表于 2015-06-23 14:13

IOS中级篇 —— 多线程 - GCD

本帖最后由 船头尺 于 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 identifierios8之前 传线程优先级 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个队列

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