文章目录
  1. 1. 前言
  2. 2. dispatch_barrier_async
  3. 3. dispatch_group
  4. 4. 参考

前言

dispatch_barrier_async 和 dispatch_group 是GDC中比较高级的用法,其作用都可以视为 等一段并发的工作完成后,接着处理某些其他事情。但二者还是有很大区别的,dipatch_barrier_async是对同一个队列的各个任务而设置一个节点的;而dispatch_group除此之外还可以对不同队列来统一设置一个节点(因此更强大)。

dispatch_barrier_async

一个dispatch barrier 允许在一个并发队列中创建一个同步点。当在并发队列中遇到一个barrier, 他会延迟执行barrier的block,等待所有在barrier之前提交的blocks执行结束。 这时,barrier block自己开始执行。 之后, 队列继续正常的执行操作。这里指定的并发队列应该是自己通过dispatch_queue_create函数创建的。如果你传的是一个串行队列或者全局并发队列,这个函数等同于dispatch_async函数。
所有在barrier block之后提交的blocks会等到barrier block结束之后才执行。

dispatch_barrier_async函数的作用

  • 实现高效率的数据库访问和文件访问 (同步)
  • 避免数据竞争 (特定到某点之后来单独处理)

例如: 在访问数据操作时,可以并行读取,因此这种操作应该放到concurrent Dispatch Queue中; 在读取完成后再统一进行其他处理操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)barrierTest {
//同dispatch_queue_create函数生成的concurrent Dispatch Queue队列一起使用
dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"----read table1-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----read table2-----%@", [NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"----barrier-- do something use both table1 and table2 -----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----do something after data operated in barrier -----%@", [NSThread currentThread]);
});
}

输出结果:

1
2
3
4
HuntTest[19408:3288590] ----read table2-----<NSThread: 0x6100002605c0>{number = 4, name = (null)}
HuntTest[19408:3288588] ----read table1-----<NSThread: 0x600000260fc0>{number = 3, name = (null)}
HuntTest[19408:3288588] ----barrier-- do something use both table1 and table2 -----<NSThread: 0x600000260fc0>{number = 3, name = (null)}
HuntTest[19408:3288588] ----do something after data operated in barrier -----<NSThread: 0x600000260fc0>{number = 3, name = (null)}

dispatch_group

队列组(dispatch_group)可以将很多队列添加到一个组里,这样做的好处是,当这个组里所有的任务都执行完了,队列组会通过一个方法通知我们。这是一个很实用的功能。

例如:

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
27
28
29
30
31
32
33
- (void)groupTest {
//1.创建队列组
dispatch_group_t group = dispatch_group_create();
//2.创建队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//3.多次使用队列组的方法执行任务, 只有异步方法
//3.1.执行1次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = 0; i < 1; i++) {
NSLog(@"group-01 - %@", [NSThread currentThread]);
}
});
//3.2.主队列执行2次循环
dispatch_group_async(group, dispatch_get_main_queue(), ^{
for (NSInteger i = 0; i < 2; i++) {
NSLog(@"group-02 - %@", [NSThread currentThread]);
}
});
//3.3.执行2次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = 0; i < 2; i++) {
NSLog(@"group-03 - %@", [NSThread currentThread]);
}
});
//4.都完成后会自动通知
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成 - %@", [NSThread currentThread]);
});
}

结果:

1
2
3
4
5
6
HuntTest[19661:3299108] group-01 - <NSThread: 0x61000006eb40>{number = 3, name = (null)}
HuntTest[19661:3299109] group-03 - <NSThread: 0x60800006ff00>{number = 4, name = (null)}
HuntTest[19661:3299109] group-03 - <NSThread: 0x60800006ff00>{number = 4, name = (null)}
HuntTest[19661:3298914] group-02 - <NSThread: 0x608000067fc0>{number = 1, name = main}
HuntTest[19661:3298914] group-02 - <NSThread: 0x608000067fc0>{number = 1, name = main}
HuntTest[19661:3298914] 完成 - <NSThread: 0x608000067fc0>{number = 1, name = main}

dispatch_group还提供了多个block之间的同步机制。

应用场景 在很多UGC(User Generated Content)产品中(如微博、赤兔、朋友圈),发一条图文并茂的动态总是群众喜闻乐见的。一个动态中可能包含多张图片,而且包含一个文字内容,因此我们可以将处理的block放到一个dispatch_group中。所有block都执行完成后,dispatch_group_notify再通知用户状态发送成功。即:

1
2
3
4
5
6
7
8
9
10
11
12
NSMutableArray *imageURLs= [NSMutableArray array];
dispatch_group_t group = dispatch_group_create(); // 1
for (UIImage *image in images) {
dispatch_group_enter(group); // 2
sendPhoto(image, success:^(NSString *url) {
[imageURLs addObject:url];
dispatch_group_leave(group); // 3
});
}
dispatch_group_notify(group, dispatch_get_global_queue(), ^{ // 4
postFeed(imageURLs, text);
});

具体可参考: http://www.jianshu.com/p/4769680b983d

参考

文章目录
  1. 1. 前言
  2. 2. dispatch_barrier_async
  3. 3. dispatch_group
  4. 4. 参考