View refreshing not triggered when ObservableObject is inherited in SwiftUI

ContentView2 view is not refreshed when model.value changes, if Model conforms to ObservableObject directly instead of inheriting SuperModel then it works fine

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))"
            }
        }

    }
}

Try it like this:

class Model: SuperModel {
    @Published var value = "initial value" {
        didSet {
            super.objectWillChange.send()
        }
    }
}

Is this a bug with @Published, seems it should "just work" as op wrote it?

You are asking for trouble if you call a will-change Publisher in a didSet handler.

Can you elaborate. Where could this bite?

Since you are calling objectWillChange, you are implying that it has not yet changed. If you call this method in a didSet handler (instead of a willSet) you are too late. While dealing with just this issue in my code, I found a discussion of post-change notification vs pre-change: https://www.pointfree.co/blog/posts/30-swiftui-and-state-management-corrections.

1 Like

Thanks!

You're quite welcome. This bug can be found in various places across the net. Its consequences are insidious: your app will seem not to let go of some state. That is, you change your code, something doesn't work, so you revert the change... and something new goes wrong that didn't before. It's like your own computer is gaslighting you.

I have just finished (I hope) unraveling the code that (unintentionally) depended on this bug. Using @Published prevents this mismatch, but every time I used it, the parts of my app that worked with the bug stopped working. I was in a deep hole.

1 Like

Well that sounds nerve racking ;) Again, thanks for sharing.

It is not clear whether this is a real bug or not though. I'm facing the same issue where I'm forced to call the objectWillChange from within a Published property of an inherited ObservableObject.

Any ideas? I haven't tried with latest Xcode beta yet.

Terms of Service

Privacy Policy

Cookie Policy