GCD多线程同步-为什么多用dispatch_group_enter和dispatch_group_level

GCD使用group进行多线程同步主要有三种方案:

  • dispatch_group_notify
  • dispatch_group_wait
  • dispatch_group_enter和dispatch_group_level

前两种方法属于同一类型使用也比较简单,但是为什么看开源项目的源码时经常看到dispatch_group_enter和dispatch_group_level搭配的使用呢?主要是因为如果在dispatch_group_async里执行的是异步代码,前两种方式会直接触发而不会等待异步任务完成。
像下边这种情况:

- (void)groupSync1
{
    dispatch_queue_t dispatchQueue = dispatch_queue_create("test.queue1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    dispatch_group_t dispatchGroup = dispatch_group_create();
    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
        
        dispatch_async(globalQueue, ^{
            
            sleep(5);
            NSLog(@"任务一完成");
        });
    });
    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
        
        dispatch_async(globalQueue, ^{
            
            sleep(8);
            NSLog(@"任务二完成");
        });
    });
    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
        NSLog(@"notify:任务都完成了");
    });
}
2018-12-17 17:24:27.899327+0800 Test[5022:529754] notify:任务都完成了
2018-12-17 17:24:32.893964+0800 Test[5022:529800] 任务一完成
2018-12-17 17:24:35.894750+0800 Test[5022:529805] 任务二完成

而使用dispatch_group_enter和dispatch_group_level就可以避免这种情况:

- (void)groupSync2
{
    dispatch_queue_t dispatchQueue = dispatch_queue_create("test.queue2", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    dispatch_group_t dispatchGroup = dispatch_group_create();
    
    dispatch_group_enter(dispatchGroup);
    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
        dispatch_async(globalQueue, ^{
            sleep(5);
            NSLog(@"任务一完成");
            dispatch_group_leave(dispatchGroup);
        });
    });
    
    dispatch_group_enter(dispatchGroup);
    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
        dispatch_async(globalQueue, ^{
            sleep(8);
            NSLog(@"任务二完成");
            dispatch_group_leave(dispatchGroup);
        });
    });
    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
        NSLog(@"notify:任务都完成了");
    });
}
2018-12-17 17:30:49.793777+0800 Test[5134:547774] 任务一完成
2018-12-17 17:30:52.797544+0800 Test[5134:547775] 任务二完成
2018-12-17 17:30:52.797843+0800 Test[5134:547707] notify:任务都完成了

你可能感兴趣的:(GCD多线程同步-为什么多用dispatch_group_enter和dispatch_group_level)