iOS多线程同步:三网络请求完成后隐藏加载器的实现方案
用DispatchGroup实现多异步请求同步,统一控制加载器
嘿,这个需求用DispatchGroup就能轻松搞定——它就是专门用来跟踪多个异步任务,等所有任务都完成后再执行统一操作的工具。咱们来调整你的代码,实现三个请求全部完成后再隐藏加载器:
核心思路
- 一开始就显示加载器(不用在每个请求成功时重复显示了)
- 创建一个
DispatchGroup实例,用来跟踪三个异步请求 - 每个请求开始前告诉Group"我要开始执行了",请求结束(无论成功/失败)时告诉Group"我做完了"
- 当Group检测到所有任务都完成时,在主线程隐藏加载器
修改后的完整代码
// 1. 一开始统一显示加载器,放在所有请求之前 DispatchQueue.main.async { EZLoadingActivity.show("LoadingContent".localized(), disableUI: true) } // 2. 创建DispatchGroup实例,用来跟踪所有请求 let requestGroup = DispatchGroup() // 处理第一个请求:getJsonProducts requestGroup.enter() // 告诉Group,当前任务启动 cms.getJsonProducts(completion: { (data) in defer { requestGroup.leave() } // 用defer确保无论成功/失败,都会通知Group任务完成 switch data { case .succes(let data): self.saveJsonFileToTheDiskProducts(path: (AppGlobalManager.sharedManager.loggedUser?.selectedLanguage)! + "/json", downloadData: data) case .error(let error): self.errorLoginMessage(txt: "MainView - Error 101: Configuration files can not be created. \(error)", title: "Blad".localized()) } }) // 处理第二个请求:getJsonNews requestGroup.enter() cms.getJsonNews(completion: { (data) in defer { requestGroup.leave() } switch data { case .succes(let data): self.saveJsonFileToTheDiskNews(path: (AppGlobalManager.sharedManager.loggedUser?.selectedLanguage)! + "/json", downloadData: data) case .error(let error): self.errorLoginMessage(txt: "MainView - Error 105: News files can not be created. \(error)", title: "Blad".localized()) } }) // 处理第三个请求:getJsonRegions requestGroup.enter() cms.getJsonRegions(completion: { (data) in defer { requestGroup.leave() } switch data { case .succes(let data): self.saveJsonFileToTheDiskRegions(path: (AppGlobalManager.sharedManager.loggedUser?.selectedLanguage)! + "/json", downloadData: data) case .error(let error): self.errorLoginMessage(txt: "MainView - Error 106: Regions files can not be created. \(error)", title: "Blad".localized()) } }) // 4. 所有任务完成后,在主线程隐藏加载器 requestGroup.notify(queue: .main) { EZLoadingActivity.hide() }
关键细节解释
requestGroup.enter():每次调用都会给Group的任务计数+1,必须和leave()一一对应,否则会导致计数异常defer { requestGroup.leave() }:defer块里的代码会在当前作用域结束前执行,这样不管请求是成功还是失败,都能确保Group收到任务完成的通知,避免加载器永远不消失requestGroup.notify(queue: .main):当Group的任务计数回到0时,会在指定的主队列(UI操作必须在主线程)执行闭包里的代码,也就是隐藏加载器
这样修改后,用户会看到加载器一开始就显示,等三个请求全部处理完毕(不管是成功还是部分失败),加载器才会隐藏,完美符合你的需求~
内容的提问来源于stack exchange,提问作者triff
相关产品推荐
相关产品推荐

