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

SwiftUI List返回详情页触发ID重复警告,Combine拉取Firestore数据排查求助

这个警告的核心原因有两个:

  1. 每次视图触发onAppear时调用startCombine都会创建新的Combine订阅,旧订阅没有被销毁,多个订阅同时修改offerRowViewModels数组,容易出现中间状态的重复数据
  2. OfferRowViewModel初始化时id默认是空字符串,id的赋值是通过Combine异步操作完成的,新数组生成的瞬间所有元素的id都是空串,ForEach检测到重复ID触发警告。你没有打印到重复ID是因为打印时机早于ForEach的检测时机、且异步赋值很快完成,你看到的都是赋值后的正常ID。

解决方案

1. 清理重复订阅

在OfferHistoryViewModel的startCombine方法开头,先清空之前的所有订阅,避免多个流同时修改数组:

func startCombine(currentUserUid: String) {
    // 新增:清空旧订阅,避免重复触发赋值
    cancellables.removeAll()
    // 原有逻辑保持不变
    for offerRowViewModel in self.offerRowViewModels {
        print("Before startCombine func: \(offerRowViewModel.id)")
    }
    // ... 剩余原有代码
}

2. 初始化时直接赋值OfferRowViewModel的id

Offer在初始化OfferRowViewModel时已经传入,不需要通过Combine异步获取id,直接在init里赋值即可,避免临时空ID的问题:

class OfferRowViewModel: ObservableObject, Identifiable {
    // 去掉初始空值,改为let类型保证id不可变
    let id: String
    var listingRepository: ListingRepository
    
    // 其他属性保持不变
    @Published var offer: Offer
    @Published var listing: Listing?
    private var cancellables = Set<AnyCancellable>()
        
    init(offer: Offer, listingRepository: ListingRepository) {
        // 新增:初始化时直接赋值id,避免异步赋值的空窗期
        self.id = offer.id ?? UUID().uuidString
        self.offer = offer
        self.listingRepository = listingRepository
        self.startCombine()
    }
    
    func startCombine() {
        // 删掉原来通过$offer赋值id的Combine代码块,不需要了
        // 只保留获取listing的逻辑即可
        listingRepository
            .$listings
            .receive(on: RunLoop.main)
            .map { listings in
                listings.first(where: { $0.id == self.offer.listingId})
            }
            .assign(to: \.listing, on: self)
            .store(in: &cancellables)
    }
}

可选优化

如果不需要保留旧的列表数据,可以在startCombine开头先清空offerRowViewModels,避免旧数据残留:

func startCombine(currentUserUid: String) {
    cancellables.removeAll()
    // 新增:清空旧数组
    offerRowViewModels.removeAll()
    // 原有逻辑保持不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:48:03