iOS GCD系列之任务组dispatch_group_t

这篇主要将对dispatch_group_t进行梳理应用,其主要用于监听管理任务组中任务完成情况,在任务完成后做一些操作处理。

最常见的几个方法

// 创建一个任务组
dispatch_group_create();

// 将任务异步提交到任务组里
dispatch_group_async(group, queue, block);

// 不使用dispatch_group_async来提交任务
// 任务组中任务数+1
dispatch_group_enter(group);

// 任务组中任务数-1与dispatch_group_enter必须成对出现
dispatch_group_leave(group);

// 等待之前任务执行完成后才继续执行
dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);

// 当任务组中任务完成,会出发出发此方法的block
dispatch_group_notify(group1, queue1,block);

实战

// 创建任务组
dispatch_group_t group = dispatch_group_create();
// 创建串行队列
dispatch_queue_t serialQueue = dispatch_queue_create("com.wynter.serial", DISPATCH_QUEUE_SERIAL);
// 创建并发队列
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.wynter.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(group, concurrentQueue, ^{
    sleep(3);
    NSLog(@"并发队列任务1,当前线程:%@", [NSThread currentThread]);
});

dispatch_group_async(group, serialQueue, ^{
    sleep(2);
    NSLog(@"串行队列任务1,当前线程:%@", [NSThread currentThread]);
});

dispatch_group_async(group, serialQueue, ^{
     sleep(2);
     NSLog(@"串行队列任务2,当前线程:%@", [NSThread currentThread]);
});

// 在任务组中并发执行,等同与dispatch_group_async(group, concurrentQueue, block)
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
    sleep(2);
    NSLog(@"并发队列任务2(enter/leave),当前线程:%@", [NSThread currentThread]);
    dispatch_group_leave(group);
});

// 开始等待阻塞全部线程,直到任务中之前任务执行完成
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"结束任务组中已执行任务的等待,继续向下执行任务");
    
dispatch_group_async(group, concurrentQueue, ^{
    sleep(1);
    NSLog(@"并发队列任务3,当前线程:%@", [NSThread currentThread]);
});
    
// 同一线程中通知任务组中队列中任务已经完成,故顺序打印通知结果
dispatch_group_notify(group, concurrentQueue, ^{
    NSLog(@"并发队列任务执行完毕,当前线程:%@", [NSThread currentThread]);
});
    
dispatch_group_notify(group, serialQueue, ^{
    NSLog(@"串行队列任务执行完毕,当前线程:%@", [NSThread currentThread]);
});
    
/*
 2017-12-15 11:11:46.761678+0800 GCD[32253:17053663] 并发队列任务2(enter/leave),当前线程{number = 4, name = (null)}
 2017-12-15 11:11:46.761678+0800 GCD[32253:17053661] 串行队列任务1,当前线程:{number = 3, name = (null)}
 2017-12-15 11:11:47.761193+0800 GCD[32253:17053660] 并发队列任务1,当前线程:{number = 5, name = (null)}
 2017-12-15 11:11:48.762938+0800 GCD[32253:17053661] 串行队列任务2,当前线程:{number = 3, name = (null)}
 2017-12-15 11:11:48.762940+0800 GCD[32356:17074006] 结束任务组中已执行任务的等待,继续向下执行任务
 2017-12-15 11:11:49.767551+0800 GCD[32253:17053661] 并发队列任务3,当前线程:{number = 3, name = (null)}
 2017-12-15 11:11:49.768026+0800 GCD[33057:17230402] 并发队列任务执行完毕,当前线程:{number = 3, name = (null)}
 2017-12-15 11:11:49.768248+0800 GCD[33057:17230226] 串行队列任务执行完毕,当前线程:{number = 5, name = (null)}
 */

1、创建串行、并发队列各一个
2、向任务组的并发队列中添加了 3秒后执行并发队列任务1、2秒后并发队列任务2(enter/leave)、1秒后执行任务3
3、向任务组的串行队列中添加了 2秒后执行串行队列任务1、2秒后执行串行队列任务2
4、在并发队列任务2(enter/leave)后添加了任务等待
5、通知任务完成

2个并发队列任务开辟两条新线程,并发执行耗时3秒,同时串行队列中的2个任务在同一线程中执行耗时4秒。因为在并发任务后添加任务组等待方法,所以并发队列任务3要等前面4个任务执行完毕才能执行,任务组总共耗时5秒,如果去掉任务等待耗时为4秒。

总结

  • 使用dispatch_sync/dispatch_async来处理同步或异步,其实完没有必要,串行并发队列完全可以满足需求,并且使用dispatch_async会导致任务组提前通知完成;
  • 任务组通知不区分串还是并行队列,任务组中所有任务执行完成才会收到通知。

你可能感兴趣的:(iOS GCD系列之任务组dispatch_group_t)