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

调用函数时App卡顿无调试日志,Firebase数据存入结构体数组问题求助

问题原因

  • 核心卡死原因:你写的while keys < 6是同步阻塞在主线程的逻辑,而Firebase的addSnapshotListener属于异步回调,必须等主线程空闲时才会执行回调内的代码。现在主线程一直跑while死循环,永远没空执行Firebase的回调,keys永远不会被更新,直接卡死主线程,所以出现APP卡顿、控制台无日志输出的问题。
  • 额外逻辑漏洞:你一共只有5个字段需要读取,就算全部读取成功keys最多也只能到5,永远达不到6,哪怕Firebase回调能执行,while循环也永远不会停止。同时你循环使用的区间是0...count,会多循环一次导致数组越界崩溃,且同一个对象重复追加了两次到数组,属于无效逻辑。

修复后的代码

// 提前定义统一的模型,后续维护更方便
struct Restaurant: Identifiable {
    let id: String
    let name: String
    let imageUrl: URL
    let rating: Double
    let url: URL
}

db.collection("parties").document(Utilities.code).addSnapshotListener { document, error in
    // 优先处理错误和空值情况
    if let error = error {
        print("error = \(error)")
        return
    }
    guard let document = document, document.exists else {
        print("文档不存在")
        return
    }
    // 统一读取所有字段,同时校验长度一致避免越界
    guard let names = document.get("yesName") as? [String],
          let imageUrls = document.get("yesImg") as? [String],
          let ids = document.get("yesId") as? [String],
          let ratings = document.get("yesRating") as? [Double],
          let urls = document.get("yesUrl") as? [String],
          names.count == imageUrls.count,
          names.count == ids.count,
          names.count == ratings.count,
          names.count == urls.count else {
        print("字段格式不匹配")
        return
    }
    // 直接组装数组,不需要额外的while循环等待
    var tempList = [RestaurantListViewModel]()
    for i in 0..<names.count {
        guard let imageUrl = URL(string: imageUrls[i]),
              let linkUrl = URL(string: urls[i]) else {
            continue
        }
        let vm = RestaurantListViewModel(
            name: names[i],
            imageUrl: imageUrl,
            id: ids[i],
            rating: ratings[i],
            url: linkUrl
        )
        tempList.append(vm)
    }
    // 更新UI请确保在主队列执行
    DispatchQueue.main.async {
        yes.list = tempList
    }
}

更优的存储方案

  • 不要把同一个对象的不同属性拆成多个独立数组存储,统一存为对应模型的数组,避免出现数组长度不一致导致的越界问题,维护成本更低。
  • 可以调整Firebase的文档结构,直接存储餐厅对象的嵌套数组,无需拆成5个独立数组,后续可以直接用Firebase自带的Codable解码能力一键解析,不需要手动逐个取字段,代码更简洁出错概率更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:15:03