问题引出
在实际开发中,APP首页的数据经常是由多个请求返回的,在下拉刷新内容的时候是需要在接收到这几个并发请求的返回数据之后才把下拉刷新的头部结束刷新,恢复正常状态,这个时候就需要实现线程的同步了。
解决方法
GCD中处理多个线程同步问题的函数有3个:dispatch_group_t 、dispatch_barrier_async、dispach_semaphore,各有各的适用环境:
1.> dispatch_group_t比较适合同步多个线程的操作, 在各个线程的任务完成后,使用dispatch_group_notify函数接收组队列通知即可.
2.> dispatch_barrier比较适合对于同一个并发队列,使队列中前几个任务完成后再执行后面的并发任务,有点类似于NSOperation里面的设置依赖.
3.> dispach_semaphore信号量是比较适合用来控制最大并发任务数的,信号量相当于可以当前可以执行的任务数,使用dispatch_semaphore_wait函数来等待信号量,当信号数大于0时才会开始执行并且使信号量减1.
所以开始提出的问题使用组队列能更方便的解决.
实际代码
// 创建线程组,以便同步这3个请求
self.groupQueue = dispatch_group_create();
[self sendRequest1];
[self sendRequest2];
[self sendRequest2];
dispatch_group_notify(self.groupQueue, dispatch_get_main_queue(), ^{
DLOG(@"结束了3个请求");
self.groupQueue = nil;
[self.tableView.mj_header endRefreshing];
});
实际发送请求时调用的函数 dispatch_group_enter(self.groupQueue)、dispatch_group_leave(self.groupQueue)
#pragma mark - 轮播广告相关
- (void) sendRequest1 {
NSMutableDictionary *params = [NSMutableDictionary dictionary];
@weakify(self);
if (self.groupQueue) {
dispatch_group_enter(self.groupQueue);
}
[[NetworkingManager new] sendHttp:CM020 content: params controller:nil animate:NO completion:^( NSDictionary *backContentDict) {
@strongify(self);
if (self.groupQueue) {
dispatch_group_leave(self.groupQueue);
}
// do some thing
} error:^(NSError *error) {
@strongify(self);
if (self.groupQueue) {
dispatch_group_leave(self.groupQueue);
}
// do some thing
}];
}