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

SwiftUI中Firestore的add回调与快照监听器是否可能引发竞态条件?

问题解答

预判正确性

你的判断完全正确,该场景确实存在竞态风险,最终会出现书籍重复的问题。

实际执行逻辑

Firestore 的所有回调默认都会派发到主队列串行执行,因此标记(1)和(2)的代码不会真的同时运行,但二者的执行顺序完全由系统调度决定,没有固定先后:

  • 调用add(_:completion:)写入数据成功后,Firestore 会同时触发两个回调:add方法自带的完成回调、你提前注册的快照监听器回调
  • 两个回调都会被提交到主队列的待执行任务队列,谁先被调度执行是完全不确定的

你预判的两种情况都会真实发生:

  • 若add的完成回调先执行:先向books追加数据,后续监听器回调直接用服务端返回的完整列表覆盖books属性,不会出现重复
  • 若监听器回调先执行:已经把包含新增书籍的完整列表赋值给books,后续add的完成回调再追加一次相同的书籍,就会出现重复数据

问题修复建议

  1. 最简方案:直接删除add方法完成回调里的self.books.append(book)逻辑即可。快照监听器已经会自动同步服务端的最新数据,不需要手动做追加操作。
  2. 如果要做本地乐观更新提升体验,可以在追加前做去重校验:先判断books中是否已经存在相同ID的Book实例,不存在再执行追加。
  3. 另外你现有代码存在逻辑错误:监听器里的guard error != nil else { completion(.networkError); return }写反了判断条件,应该改为guard error == nil else,否则无错误时反而会返回网络错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 10:30:06