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

为什么我的Swift闭包没有按照预期时机执行?

问题成因

你遇到的是iOS开发中非常典型的异步回调执行时序问题:

  • observeSingleEvent 是Firebase提供的异步网络请求接口,你传入的闭包不会立刻执行,系统会先把请求发出去,然后立刻继续执行闭包后面的同步代码
  • 所有同步执行的for循环代码会先跑完,等网络请求陆续返回结果后,才会依次调用你传入的闭包,这就是为什么你会看到闭包在整个for循环结束后才批量执行的现象
  • 你当前通过UserDefaults中转数据的逻辑完全不适用异步场景,请求还没返回的时候你去读本地存储的值自然是空的

解决方案

你可以把需要在拿到数据后执行的逻辑,直接放到闭包内部执行,就可以保证时序正确:

for id in myCircles {
    ref.child("\(id)").observeSingleEvent(of: .value, with: { snapshot in
        let value = snapshot.value as? NSDictionary
        let circleName = value?["name"] as? String ?? ""
        let circleCategory = value?["category"] as? String ?? ""
        let circleID = value?["id"] as? String ?? ""
                
        // 直接在回调里执行后续逻辑,不需要通过UserDefaults中转
        self.addCircle(circleName: circleName, circleID: circleID, circleCategory: circleCategory)
        // 如果确实需要本地缓存,也放在这里执行
        self.defaults.setValue([circleName, circleID, circleCategory], forKey: "newestCircle"+"\(id)")
   }) { error in
       print("请求失败: \(error.localizedDescription)")
   }
}

如果你需要等所有id的请求都返回后再统一执行后续操作,可以使用GCD的DispatchGroup来管理多个异步任务的时序:

let group = DispatchGroup()

for id in myCircles {
    group.enter()
    ref.child("\(id)").observeSingleEvent(of: .value, with: { snapshot in
        defer { group.leave() }
        let value = snapshot.value as? NSDictionary
        let circleName = value?["name"] as? String ?? ""
        let circleCategory = value?["category"] as? String ?? ""
        let circleID = value?["id"] as? String ?? ""
        
        self.addCircle(circleName: circleName, circleID: circleID, circleCategory: circleCategory)
        self.defaults.setValue([circleName, circleID, circleCategory], forKey: "newestCircle"+"\(id)")
   }) { error in
       group.leave()
       print("请求失败: \(error.localizedDescription)")
   }
}

// 所有请求完成后会执行这里的代码
group.notify(queue: .main) {
    print("所有圈子数据加载完成")
    // 这里可以放需要等全部加载完再执行的逻辑,比如刷新UI
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:06:03