上一讲我们稍微提了一下GCD的线程间通信.戳:GCD线程间的通信
这一讲我们来谈谈GCD调度组.
不知道大家有没有这么一个需求.就是一个VC比如主页吧.有许多的接口.如果是每下来一个接口就刷新一波数据的话,那么体验上就十分的差.
整理一下需求.就是统一的进行网络请求.然后等所有的网络请求回来了之后.刷新接口.
拿AFN举例吧.AFN网络请求的话默认就是给你异步请求的.比如
{
NSLog(@"begin");
[AFN xxxBlock^{
NSLog(@"1");
}];
[AFN xxxBlock^{
NSLog(@"2");
}];
[AFN xxxBlock^{
NSLog(@"3");
}];
[AFN xxxBlock^{
NSLog(@"4");
}];
NSLog(@"end");
}
因为请求的时候是异步请求.只是数据回来了之后才回调主线程.
1.2.3.4的打印顺序是不定的.有人说在end后处理回调…那我只能…让你多看看多线程.
这个时候我们就可以利用Dispatch_Group调度组了
// dispatch_group_create();
// dispatch_group_wait(<#dispatch_group_t _Nonnull group#>, <#dispatch_time_t timeout#>)
// dispatch_group_enter(<#dispatch_group_t _Nonnull group#>)
// dispatch_group_async(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
// dispatch_group_async_f(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#void * _Nullable context#>, <#dispatch_function_t _Nonnull work#>)
// dispatch_group_notify(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
// dispatch_group_notify_f(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#void * _Nullable context#>, <#dispatch_function_t _Nonnull work#>)
// dispatch_group_leave(<#dispatch_group_t _Nonnull group#>)
是不是看得很头大,其实我们可以分类一下
/// 创建一个GCD调度组
// dispatch_group_create();
/// 将任务添加进调度组.
// dispatch_group_async(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
/// 将任务添加进调度组.可以传递参数
// dispatch_group_async_f(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#void * _Nullable context#>, <#dispatch_function_t _Nonnull work#>)
/// 调度组"引用" + 1(可以理解为任务进入调度组的标记)
// dispatch_group_enter(<#dispatch_group_t _Nonnull group#>)
/// 调度组"引用" - 1(可以理解为我们将任务标记为执行完毕了).
// dispatch_group_leave(<#dispatch_group_t _Nonnull group#>)
/// 当所有任务执行完毕后.执行的方法
// dispatch_group_notify(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
/// 和上面一样.不过可以带参数
// dispatch_group_notify_f(<#dispatch_group_t _Nonnull group#>, <#dispatch_queue_t _Nonnull queue#>, <#void * _Nullable context#>, <#dispatch_function_t _Nonnull work#>)
/// 等待调度组执行完毕.或者在等待了后面的超时时长后算为执行完毕.
// dispatch_group_wait(<#dispatch_group_t _Nonnull group#>, <#dispatch_time_t timeout#>)
dispatch_group_t group = dispatch_group_create();
dispatch_group_entry(group);
方法可以使GCD调度组的引用+1.当引用不为0的时候调度组就不会被标记为执行完毕.对应的出组方法为dispatch_group_leave(group)
这里不推荐用async,因为block执行完毕就算这个async里面的任务执行完了,如果在block里面开启了新的线程,那么不会等待新线程的执行完毕
dispatch_group_leave(group)
可以使调度组的引用-1.
如果最后不能减小到0的话.那么调度组就不能被视为执行完毕.
如果没有传递参数的需求的话使用
dispatch_group_notify
.有传递参数的需求使用dispatch_group_notify_f
.因为一般是在前面的网络回调中数据都处理完毕了.那么直接在notify的回调队列传入dispatch_get_main_queue()
即可
如果有设置超时时长需求的,可以直接写上
dispatch_group_wait( ,)
,可以理解为调度组最大执行时间.超时了就不会等待leave了**对于想等待完全执行完毕的可以使用
dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)