GCD详细使用笔记

第一、通过GCD创建队列(Queue)  

创建队列方式有以下几种:

  1、创建一个串行队列:

1 dispatch_queue_t queue =dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);

  2、创建一个并行队列:

1 dispatch_queue_t queue =dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);

  3、获取一个全局的队列:

1 // 第1个参数表示队列执行的优先级:
2 // DISPATCH_QUEUE_PRIORITY_HIGH-高优先级
3 // DISPATCH_QUEUE_PRIORITY_DEFAULT-中优先级
4 // DISPATCH_QUEUE_PRIORITY_LOW-低优先级
5 // DISPATCH_QUEUE_PRIORITY_BACKGROUND-最低优先级
6 // 第2个参数暂不支持,传0即可;
7 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  4、获取一个运行在主线程中的队列:

1 dispatch_queue_t queue = dispatch_get_main_queue();

 

第二、队列的使用

1、执行一个串行队列:串行队列的特点是当前一个任务执行完毕后,后一个任务才开始执行。

 1 dispatch_queue_t queue =dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
 2     
 3     dispatch_async(queue, ^{
 4        
 5         NSLog(@"任务1 start");
 6         sleep(4);
 7         NSLog(@"任务1 end");
 8     });
 9     
10     dispatch_async(queue, ^{
11        
12         NSLog(@"任务2 start");
13         sleep(2);
14         NSLog(@"任务2 end");
15     });

2、执行一个并行队列:并行队列的特点是可以同时执行多个任务,在执行并行队列的时候,利用了信号量来控制同时执行的线程个数。

 1 dispatch_queue_t queue =dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
 2     dispatch_semaphore_t semaphore =dispatch_semaphore_create(2);//这里指定可以同时执行的任务个数
 3     
 4     dispatch_async(queue, ^{
 5        
 6         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
 7         NSLog(@"任务1 start");
 8         sleep(4);
 9         NSLog(@"任务1 end");
10         dispatch_semaphore_signal(semaphore);
11     });
12     
13     dispatch_async(queue, ^{
14         
15         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
16         NSLog(@"任务2 start");
17         sleep(3);
18         NSLog(@"任务2 end");
19         dispatch_semaphore_signal(semaphore);
20     });
21     
22     dispatch_async(queue, ^{
23         
24         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
25         NSLog(@"任务3 start");
26         sleep(8);
27         NSLog(@"任务3 end");
28         dispatch_semaphore_signal(semaphore);
29     });
30     dispatch_async(queue, ^{
31         
32         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
33         NSLog(@"任务4 start");
34         sleep(6);
35         NSLog(@"任务4 end");
36         dispatch_semaphore_signal(semaphore);
37     });

3、执行一个并行队列:上面我们已经讲述了如何执行一个并行队列,并且指定并行任务最大个数,那么下面还有一个方法可以实现,就是利用

dispatch_barrier_async(并行队列中设置分界线),分界线的作用就是,将一组并行任务切割成多组并行任务顺序执行。我们也经常使用它来解决由于并发导致的数据不同步问题。

 1 dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
 2     
 3     dispatch_async(queue, ^{
 4        
 5         NSLog(@"任务1 start");
 6         sleep(4);
 7         NSLog(@"任务1 end");
 8     });
 9     
10     dispatch_async(queue, ^{
11         
12         NSLog(@"任务2 start");
13         sleep(3);
14         NSLog(@"任务2 end");
15     });
16     
17     dispatch_barrier_async(queue, ^{
18        
19         NSLog(@"--------------前面的并发任务执行完毕,准备执行下面的并发任务--------------");
20         sleep(2);
21     });
22     
23     dispatch_async(queue, ^{
24         
25         NSLog(@"任务3 start");
26         sleep(2);
27         NSLog(@"任务3 end");
28     });
29     
30     dispatch_barrier_async(queue, ^{
31        
32         NSLog(@"--------------前面的并发任务执行完毕,准备执行下面的并发任务--------------");
33         sleep(2);
34     });
35     
36     dispatch_async(queue, ^{
37         
38         NSLog(@"任务4 start");
39         sleep(5);
40         NSLog(@"任务4 end");
41     });
42     dispatch_async(queue, ^{
43         
44         NSLog(@"任务5 start");
45         sleep(3);
46         NSLog(@"任务5 end");
47     });
48     dispatch_async(queue, ^{
49         
50         NSLog(@"任务6 start");
51         sleep(5);
52         NSLog(@"任务6 end");
53     });

4、执行一个串行队列,并且我想知道这组队列什么时候执行完毕:

 1 dispatch_queue_t queue =dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
 2     dispatch_group_t group =dispatch_group_create();
 3     dispatch_group_async(group, queue, ^{
 4         NSLog(@"任务1 start");
 5         sleep(2);
 6         NSLog(@"任务1 end");
 7     });
 8     dispatch_group_async(group, queue, ^{
 9         NSLog(@"任务2 start");
10         sleep(2);
11         NSLog(@"任务2 end");
12     });
13     dispatch_group_async(group, queue, ^{
14         NSLog(@"任务3 start");
15         sleep(2);
16         NSLog(@"任务3 end");
17     });
18     
19 //    //方法一:
20 //    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
21 //    //这里会等待group中的所有任务执行完成后才会向下执行
22 //    NSLog(@"所有任务全部执行完毕");
23     
24     //方法二:
25     dispatch_group_notify(group, queue, ^{
26         
27         NSLog(@"所有任务全部执行完毕");
28     });
29     //这里不会等到group中所有的任务执行完成后才会向下执行
30     NSLog(@"所有任务还没执行完毕");

5、执行一个并行队列,并且我想知道这组队列什么时候执行完毕:

 1 dispatch_queue_t queue =dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
 2     dispatch_semaphore_t semaphore =dispatch_semaphore_create(2);//这里指定可以同时执行的任务个数
 3     dispatch_group_t group =dispatch_group_create();
 4     dispatch_group_async(group, queue, ^{
 5         
 6         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
 7         NSLog(@"任务1 start");
 8         sleep(7);
 9         NSLog(@"任务1 end");
10         dispatch_semaphore_signal(semaphore);
11     });
12     dispatch_group_async(group, queue, ^{
13         
14         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
15         NSLog(@"任务2 start");
16         sleep(5);
17         NSLog(@"任务2 end");
18         dispatch_semaphore_signal(semaphore);
19     });
20     dispatch_group_async(group, queue, ^{
21         
22         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
23         NSLog(@"任务3 start");
24         sleep(3);
25         NSLog(@"任务3 end");
26         dispatch_semaphore_signal(semaphore);
27     });
28     dispatch_group_async(group, queue, ^{
29         
30         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
31         NSLog(@"任务4 start");
32         sleep(2);
33         NSLog(@"任务4 end");
34         dispatch_semaphore_signal(semaphore);
35     });
36     
37 //    //方法一:
38 //    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
39 //    //这里会等待group中的所有任务执行完成后才会向下执行
40 //    NSLog(@"所有任务全部执行完毕");
41     
42     //方法二:
43     dispatch_group_notify(group, queue, ^{
44         
45         NSLog(@"所有任务全部执行完毕");
46     });
47     //这里不会等到group中所有的任务执行完成后才会向下执行
48     NSLog(@"所有任务还没执行完毕");

 

第三、利用GCD实现单例模式

 1 - (MySingletonObj *)shareObj{
 2     
 3     static MySingletonObj *singleton;
 4     static dispatch_once_t onceToken;
 5     dispatch_once(&onceToken, ^{
 6         //这里在整个程序的生命周期内只会执行一次
 7         singleton =[[MySingletonObj alloc] init];
 8     });
 9     return singleton;
10 }

 第四、利用GCD实现一个定时任务

1 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
2         
3      NSLog(@"3秒钟到了,我开始执行了");
4 });

第五、利用GCD实现一个循环操作:这个方法是同步运行的,类似于for循环

1 dispatch_queue_t queue =dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
2 //    dispatch_queue_t queue =dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
3     dispatch_apply(5, queue, ^(size_t index) {
4         
5         //注意:如果queue是串行队列,那么index是按照0、1、2、3、4的顺序执行
6         //     如果queue是并行队列,那么index就不一定是按照顺序执行了
7         NSLog(@"%@", @(index));
8     });

第六、某些情况下,我们可能会想让Queue暂时停止一下,然后在某个时刻恢复处理,这时就可以使用dispatch_suspend以及dispatch_resume函数。暂停时,如果已经有block正在执行,那么不会对该block的执行产生影响。dispatch_suspend只会对还未开始执行的block产生影响。

1 //暂停
2 dispatch_suspend(globalQueue)
3 //恢复
4 dispatch_resume(globalQueue)

第七、设置队列的优先级

iOS8之后:

dispatch_qos_class_t qosClass = QOS_CLASS_UTILITY;
// qos指定优先级,包括如下(又高到底):
/**
QOS_CLASS_USER_INTERACTIVE
QOS_CLASS_USER_INITIATED
QOS_CLASS_UTILITY
QOS_CLASS_BACKGROUND
QOS_CLASS_DEFAULT
*/
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, qosClass, 0);
        return dispatch_queue_create(label, attr);

iOS8之前:

long identifier = DISPATCH_QUEUE_PRIORITY_HIGH;
// identifier优先级,包括(由高到低):
/**
DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_BACKGROUND
DISPATCH_QUEUE_PRIORITY_DEFAULT
*/
dispatch_queue_t queue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(queue, dispatch_get_global_queue(identifier, 0));

 

以上是关于GCD中常用的一些函数和用法,其他方面有兴趣的可以到官网了解具体使用。

 

posted @ 2016-03-16 18:37  zbblogs  阅读(336)  评论(0编辑  收藏  举报