使用dispatch_group_t导致网络请求回调执行两次的原因咨询
问题原因及解决方案
问题根源
你当前对dispatch_group_t的用法存在错误:
dispatch_group_async的block只是同步执行了getOneData方法,但getOneData内部的网络请求是异步操作,这个block会立刻执行完毕,导致dispatch_group_notify提前触发,调用[self.tableView.mj_header endRefreshing]。- 此时网络请求还在后台处理,当请求完成触发回调时,又会执行回调内的代码(比如
reloadData或再次调用endRefreshing)。下拉刷新控件(mj_header)在重复执行endRefreshing时会出现状态异常,进而再次触发整个刷新流程,最终导致getOneData和getTwoData被二次调用,回调也就执行了两次。
正确实现方式
需要让dispatch_group_t真正等待网络请求完成,要配合dispatch_group_enter和dispatch_group_leave使用:
1. 修改主逻辑代码
dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(0, 0); [self.permissionData removeAllObjects]; dispatch_group_enter(group); dispatch_async(queue, ^{ [self getOneDataWithCompletion:^{ dispatch_group_leave(group); }]; }); [self.bannerData removeAllObjects]; dispatch_group_enter(group); dispatch_async(queue, ^{ [self getTwoDataWithCompletion:^{ dispatch_group_leave(group); }]; }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ [self.tableView.mj_header endRefreshing]; });
2. 修改网络请求方法,增加完成回调
- (void)getOneDataWithCompletion:(void(^)(void))completion { [self requestData:^(id _Nullable datas, NSError * _Nullable error) { if (error != nil) { // 错误分支也要调用completion,避免group永久等待 if (completion) completion(); } else { if ([datas isKindOfClass:[NSArray class]]) { self.datas = datas; } [self.tableView reloadData]; if (completion) completion(); } }]; }
(getTwoData做同样修改即可)
关键说明
dispatch_group_enter:在每个网络请求开始前调用,告诉group还有一个未完成的任务;dispatch_group_leave:在网络请求回调(成功/失败)中调用,告诉group该任务已完成;- 只有当所有
enter都对应了leave,dispatch_group_notify才会触发,确保所有网络请求完成后再结束下拉刷新,避免重复触发刷新逻辑。
内容的提问来源于stack exchange,提问作者HR Jackson
相关产品推荐
相关产品推荐

