GCD调度组(dispatch_group)

上一讲我们稍微提了一下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#>)

用例

1.创建GCD调度组

dispatch_group_t group = dispatch_group_create();

2.增加GCD调度组"引用"

dispatch_group_entry(group);方法可以使GCD调度组的引用+1.当引用不为0的时候调度组就不会被标记为执行完毕.对应的出组方法为dispatch_group_leave(group)

这里不推荐用async,因为block执行完毕就算这个async里面的任务执行完了,如果在block里面开启了新的线程,那么不会等待新线程的执行完毕

3.在网络请求回调处理完数据之后减少GCD调度组"引用"

dispatch_group_leave(group)可以使调度组的引用-1.

如果最后不能减小到0的话.那么调度组就不能被视为执行完毕.

4.在所有网络回调都处理完成之后刷新UI

如果没有传递参数的需求的话使用dispatch_group_notify.有传递参数的需求使用dispatch_group_notify_f.因为一般是在前面的网络回调中数据都处理完毕了.那么直接在notify的回调队列传入dispatch_get_main_queue()即可

超时等待时长

如果有设置超时时长需求的,可以直接写上dispatch_group_wait( ,),可以理解为调度组最大执行时间.超时了就不会等待leave了**

对于想等待完全执行完毕的可以使用dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)

你可能感兴趣的:(多线程)