需求场景:如,A网络请求 和 B网络请求完成后,刷新界面。
方案一:通过GCD的信号量semaphore
- (void)twoRequest {
// 创建 任务组
dispatch_group_t group = dispatch_group_create();
// 获取一个全局队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建 信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 执行循序1
dispatch_group_async(group, queue, ^{
// 第一个请求
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 异常处理
}
// 执行顺序4/6
dispatch_semaphore_signal(semaphore);
}];
});
// 执行循序2
dispatch_group_async(group, queue, ^{
// 第二个请求
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 异常处理
}
// 执行顺序4/6
dispatch_semaphore_signal(semaphore);
}];
});
dispatch_group_notify(group, queue, ^{
// 执行循序3
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 执行顺序5
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 执行顺序7
dispatch_async(dispatch_get_main_queue(), ^{ 刷新界面 });
});
}
信号量可以用车库中的空闲车位来表示。当要往车库停车时,如果车库已满,则需等待(阻塞线程)。
- 关于信号量的三个方法
1.创建一个车库,value
表示车库中空闲车位的数量
dispatch_semaphore_create(long value);
2.往车库里停一辆车,如果没有空车位,则一直会等待在车库外,等待时间为dispatch_time_t timeout
,如果有空车位则停车,减少一个空车位
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
3.从车库中开走一辆车,增加一个空闲车位
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
- 关于任务组的三个方法
1、函数dispatch_group_notify(group1, queue1,block);
监听group组中任务的完成状态,当所有的任务都执行完后,触发block块,执行总结性处理。
2、函数dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)
当前线程暂停,等待此函数上面的任务执行完成后,线程才继续执行。
3、函数dispatch_group_async(group, queue, block);
将block任务添加到queue队列,并被group组管理。
方案二: dispatch_group_enter
{
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group); // 任务 + 1
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 异常处理
}
dispatch_group_leave(group); // 任务 - 1
}];
dispatch_group_enter(group); // 任务 + 1
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 异常处理
}
dispatch_group_leave(group); // 任务 - 1
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
NSLog(@"Group End!");
});
}
简单来说,就是 dispatch_group_enter
会对 group 的内部计数 +1,dispatch_group_leave
会对 group 的内部计数 -1,就类似以前的 retain
和 release
方法。也就是维护了一个计数器。