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

Swift:如何从completion block获取多城市天气加载完成后的完整数组

多接口请求聚合统一回调实现方案

核心改造逻辑

  • 调整completion闭包入参类型,从单个Weather实例改为[Weather]类型的数组
  • 预先过滤无效请求URL,统计实际需要发起的请求总数,避免因原逻辑中跳过无效URL的分支导致“全部完成”的判断永远无法触发
  • 引入轻量串行同步队列,保护共享数据(结果收集数组、请求完成计数器)的线程安全,解决多线程并发回调下的数据竞争崩溃问题
  • 当已完成的请求数和总有效请求数相等时,切回主线程触发统一结果回调

改造后的代码实现

1. 重构getCityWeather方法

public func getCityWeather(completion: @escaping ([Weather]) -> Void) {
    // 存储所有收集到的天气数据
    var weatherResult: [Weather] = []
    // 串行队列保证多线程下的数据操作安全
    let syncQueue = DispatchQueue(label: "weather.collect.sync")
    // 预先过滤出所有有效的请求URL
    let validURLs = citiesGeo.compactMap { geo in
        let urlString = "https://api.weather.yandex.ru/v2/forecast?lat=\(geo.latitude)&lon=\(geo.longitude)"
        return URL(string: urlString)
    }
    // 无有效请求时直接回调空数组
    guard !validURLs.isEmpty else {
        DispatchQueue.main.async {
            completion([])
        }
        return
    }
    // 记录已完成的请求数量
    var completedCount = 0
    // 遍历所有有效URL发起请求
    validURLs.forEach { url in
        self.loadManager.getWeather(url: url) { weather in
            syncQueue.async {
                weatherResult.append(weather)
                completedCount += 1
                // 所有请求完成时触发统一回调
                if completedCount == validURLs.count {
                    DispatchQueue.main.async {
                        completion(weatherResult)
                    }
                }
            }
        }
    }
}

2. 调整调用处的逻辑

原来viewDidLoad中的调用无需额外做线程切换,直接接收完整数组即可:

override func viewDidLoad() {
    super.viewDidLoad()
    weatherLoader.getCityWeather { weatherList in
        // 这里拿到的是加载完成的全量城市天气数据
        print("共获取\(weatherList.count)条天气数据:\(weatherList)")
    }
}

注意事项

  • 线程安全保护不能省略:网络请求的回调通常在不同子线程并发触发,没有同步队列保护的情况下,同时修改数组和计数器会引发数据错乱、数组越界甚至崩溃
  • 回调线程提前切换:拿到数据后通常需要刷新UI,在函数内部提前切回主线程,能避免调用方重复处理线程跳转
  • 兼容异常场景:如果loadManager.getWeather接口存在请求失败/超时无回调的情况,需要先调整该接口逻辑,保证无论请求成功、失败都一定会触发收尾回调,否则一旦有请求异常,整个聚合流程会永久阻塞

内容的提问来源于stack exchange,提问作者IlyaNester

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 14:45:02