当 ObservedObject 更改时,SwiftUI 视图不会更新

Oua*_*lal 6 xcode mvvm observable swift swiftui

我有一个内容视图,其中使用 ForEach 显示项目列表

@ObservedObject var homeVM : HomeViewModel

var body: some View {
    ScrollView (.horizontal, showsIndicators: false) {
        HStack(spacing: 10) {
            Spacer().frame(width:8)
            ForEach(homeVM.favoriteStores , id: \._id){ item in
                StoreRowOneView(storeVM: item)
            }
            Spacer().frame(width:8)
        }
    }.frame(height: 100)
}
Run Code Online (Sandbox Code Playgroud)

而我的ObservableObject包含

@Published var favoriteStores = [StoreViewModel]()

并StoreViewModel定义如下

class StoreViewModel  : ObservableObject {
    @Published var store:ItemStore

    init(store:ItemStore) {
        self.store = store
    }

    var _id:String {
        return store._id!
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我直接填充数组,它工作正常,我可以看到商店列表,但如果我在网络调用(后台作业)后填充数组,则视图没有收到更改通知

 StoreApi().getFavedStores(userId: userId) { (response) in
            guard response != nil else {
                self.errorMsg = "Something wrong"
                self.error = true
                return
            }
            self.favoriteStores = (response)!.map(StoreViewModel.init)
            print("counnt favorite \(self.favoriteStores.count)")
        }
Run Code Online (Sandbox Code Playgroud)

但奇怪的是: - 如果我添加一个显示数组项计数的文本,视图将收到通知并且一切正常

那就是我的意思 :

    @ObservedObject var homeVM : HomeViewModel
    var body: some View {
        ScrollView (.horizontal, showsIndicators: false) {
            HStack(spacing: 10) {
                Spacer().frame(width:8)
                ForEach(homeVM.favoriteStores , id: \._id){ item in
                    StoreRowOneView(storeVM: item)
                }
                Text("\(self.homeVM.favoriteStores.count)").frame(width: 100, height: 100)
                Spacer().frame(width:8)
            }
        }.frame(height: 100)
    }
Run Code Online (Sandbox Code Playgroud)

对此有任何解释吗?

Asp*_*eri 0

我将从将结果转发到主队列开始,如下所示

DispatchQueue.main.async {
    self.favoriteStores = (response)!.map(StoreViewModel.init)
}
Run Code Online (Sandbox Code Playgroud)

Next...ForEach跟踪id参数,所以应该确保_id后面的结果有不同的s,否则ForEach不会被标记为需要更新

ForEach(homeVM.favoriteStores , id: \._id){ item in
    StoreRowOneView(storeVM: item)
}
Run Code Online (Sandbox Code Playgroud)