You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS多线程同步:三网络请求完成后隐藏加载器的实现方案

用DispatchGroup实现多异步请求同步,统一控制加载器

嘿,这个需求用DispatchGroup就能轻松搞定——它就是专门用来跟踪多个异步任务,等所有任务都完成后再执行统一操作的工具。咱们来调整你的代码,实现三个请求全部完成后再隐藏加载器:

核心思路

  1. 一开始就显示加载器(不用在每个请求成功时重复显示了)
  2. 创建一个DispatchGroup实例,用来跟踪三个异步请求
  3. 每个请求开始前告诉Group"我要开始执行了",请求结束(无论成功/失败)时告诉Group"我做完了"
  4. 当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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:28:54