因為我的實際代碼有點復雜,這里有一個簡化的類結構,我可以用它來重現相同的意外行為。
這是我的子類的基本資料物件:
class People: Identifiable {
var name: String
required init(name: String) {
self.name = name
}
}
class Men: People {
}
然后我使用另一個類,它也充當超類,但也使用People.
class SuperMankind<PlayerType: People> {
var people: [PlayerType] = []
}
class Mankind: SuperMankind<Men> {
}
現在我想Mankind在我的 ViewModel 中使用這個這個子類,它是一個 ObservableObject。
class ViewModel: ObservableObject {
@Published var mankind: Mankind
init(_ m: Mankind) {
mankind = m
}
}
struct TestView: View {
@StateObject var viewModel = ViewModel(Mankind())
var body: some View {
VStack {
Button("Add") {
viewModel.mankind.people.append(Men(name: Int.random(in: 0...1000).description))
}
List {
ForEach(viewModel.mankind.people) {
Text($0.name)
}
}
}
}
}
但是如果我點擊添加按鈕,我的視圖不會更新,我不知道為什么。我發現如果我將以下代碼添加到我的按鈕操作中,視圖會更新。但在我看來,這個手動呼叫應該不是必要的,所以我認為我做錯了什么。
viewModel.objectWillChange.send()
uj5u.com熱心網友回復:
ObservableObject 要求其欄位是 structs ,而不是 classes。
我稍微更改了您的代碼,它起作用了:
protocol SuperMankind {
associatedtype PlayerType
var people: [PlayerType] { get set }
}
struct Mankind: SuperMankind {
var people: [Men] = []
}
截圖在這里
重新你的解決方案(因為我不能評論):
Array<Men>是一個結構,盡管陣列包含類參考。這就是為什么您的代碼現在可以作業的原因,就像之前您直接持有對您的類的參考一樣ObservableObject(因此沒有更新視圖)。
uj5u.com熱心網友回復:
@SwiftSharp 感謝您的回答,associatedType我沒有想到這一點。但是@Published欄位必須是結構體是不正確的考慮這個解決方案,我現在會選擇它,因為我不想讓我的所有函式都發生變異。
class People: Identifiable {
var name: String
required init(name: String) {
self.name = name
}
}
class Men: People {
}
class SuperMankind<PlayerType: People>: ObservableObject {
@Published var people: [PlayerType] = []
}
class Mankind: SuperMankind<Men> {
}
struct TestView: View {
@StateObject var viewModel = Mankind()
var body: some View {
VStack {
Button("Add") {
viewModel.people.append(Men(name: Int.random(in: 0...1000).description))
}
List {
ForEach(viewModel.people) {
Text($0.name)
}
}
}
}
}
我的問題是ViewModel該類不是必需的,而且我的超類(持有 people 陣列)不是 ObervableObject。
在這里編輯只是為了完成:這也將解決我的初始代碼問題,使用 ViewModel 類,但不是子類化 ObservableObject 我將從子類化 from Mankind,它已經通過子類化 SuperMankind 符合 ObservableObject :
class ViewModel: Mankind {
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/367566.html
