SwiftUI继承ObservableObject时不触发视图刷新

View refreshing not triggered when ObservableObject is inherited in SwiftUI

ContentView2视图在model.value变化时不刷新,如果Model直接符合ObservableObject而不是继承SuperModel则可以正常工作

class SuperModel: ObservableObject {

}

class Model: SuperModel {
    @Published var value = ""
}

struct ContentView2: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}

使用 ObjectWillChange 解决指定的问题。

这是工作代码:

import SwiftUI

class SuperModel: ObservableObject {

}

class Model: SuperModel {
    var value: String = "" {
        willSet { self.objectWillChange.send() }
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text("Model Value1: \(model.value)")
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text("Model Value2: \(model.value)")
        }
    }
}

这看起来确实是个严重的缺陷。

class SuperModel: ObservableObject {
}

class Model: SuperModel {
    @Published var value = ""
}

我看到 value 已更改并按预期保留新的,但 DynamicProperty 功能不起作用

以下变体对我有用 (Xcode 11.2 / iOS 13.2)

class SuperModel: ObservableObject {
    @Published private var stub = "" // << required !!!
}

class Model: SuperModel {
    @Published var value = "" {
        willSet { self.objectWillChange.send() } // < works only if above
    }
}

也可以考虑这种情况:

class SuperModel {
}

class Model: SuperModel, ObservableObject {
    @Published var value = ""
}

这是您示例的工作变体。看到要能够工作,不仅需要链接发布者,而且至少需要一个 Published 属性。左右,它在某些情况下可能会有所帮助。

import SwiftUI

class SuperModel: ObservableObject {
    // this is workaround but not real trouble.
    // without any value in supermodel there is no real usage of SuperModel at all
    @Published var superFlag = false
}

class Model: SuperModel {
    @Published var value = ""
    override init() {
        super.init()
        _ = self.objectWillChange.append(super.objectWillChange)
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

将代码更改为

var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text(model.superFlag.description)
            Button("change super flag") {
                self.model.superFlag.toggle()
            }
        }

    }

你可以看到如何同时使用你的超模