iOS 多线程 GCD (三)

GCD 队列组:dispatch_group

有些时候需要分别异步执行多个耗时的操作,等到耗时的操作全部完成之后,再回到主线程执行一些任务,这个时候就会用到 GCD 队列组。

dispatch_group_notify

监听 group 中任务的完成状态,当所有的任务都执行完毕后,追加任务到 group 中,并且执行任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"任务一完成");
});

dispatch_group_async(group, queue, ^{
NSLog(@"任务二完成");
});

dispatch_group_async(group, queue, ^{
NSLog(@"任务三完成");
});
//在分组的所有任务完成后触发
dispatch_group_notify(group, queue, ^{
NSLog(@"所有任务完成");
});

但是网络请求是步的耗时的,上述的方法并不适用于多个网络请求的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"请求一");
});
});

dispatch_group_async(group, queue, ^{
NSLog(@"任务二完成");
});

dispatch_group_async(group, queue, ^{
NSLog(@"任务三完成");
});
//在分组的所有任务完成后触发
dispatch_group_notify(group, queue, ^{
NSLog(@"所有任务完成");
});

此时输出”所有任务完成”之后,才会输出”请求一”。关于多个网络请求可以使用 dispatch_group_enter 和 dispatch_group_leave

dispatch_group_enter和dispatch_group_leave

dispatch_group_enter 表示一个任务追加到 group,执行一次,相当于 group 中未执行完毕的任务数+1;

dispatch_group_leave 表示一个任务离开了 group,执行一次,相当于 group 中未执行完毕的任务数-1;

当group中未执行完毕的任务数为0时,执行追加到 dispatch_group_notify 中的任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);

dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"任务1");
dispatch_group_leave(group);
});
});

dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
NSLog(@"任务2");
dispatch_group_leave(group);
});

dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
NSLog(@"任务3");
dispatch_group_leave(group);
});

dispatch_group_notify(group, queue, ^{
NSLog(@"完成");
});

dispatch_group_wait

dispatch_group_wait 同 dispatch_group_notify 的功能类似,在 group 上的任务完成前,dispatch_group_wait 会阻塞当前线程,所以不能放在主线程中调用。当 group 上的任务完成,或者等待的时间超过了设置的超时时间就会结束等待。

1
long dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);