Reputation: 41
I'm migrating old ObservableObjects to the new Observation method with @Observable macro. What happens if I don't mark the previously unpublished properties with @ObservationIgnored?
Example:
original class:
class Class1: ObservableObject {
@Published var a: Int = 1
var b: Int = 2
}
new class:
@Observable class Class2 {
var a: Int = 1
var b: Int = 2 // Do I absolutely need to use @ObservationIgnored here?
}
Thank you!
Upvotes: 0
Views: 417
Reputation: 273540
Removing @ObservationIgnored
from an @Observable
class is roughly similar to adding @Published
to an ObservableObject
. It can be a breaking change, in the sense that it might change existing behaviour.
A simple but contrived example is:
@Observable
class Foo {
var x = 0
@ObservationIgnored
var y = 0
}
struct ContentView: View {
@State var foo = Foo()
var body: some View {
VStack {
Text(foo.x, format: .number)
Text(foo.y, format: .number)
Button("Change X") {
foo.x += 1
}
Button("Change Y") {
foo.y += 1
}
}
}
}
Here, tapping "Change Y" will never change the second Text
. It is only after you tap "Change X", does the second Text
update to reflect the current value of foo.y
.
Do note that this doesn't mean foo.y += 1
doesn't change the value of foo.y
. foo.y
is still set correctly. It's just the view's body
is not called to reflect the change.
Removing @ObservationIgnored
will change the behaviour. Tapping "Change Y" will now always update the view.
If no view has a dependency on the "ignored" property (this means you are not calling the getter/setter of the property in body
), then there will be no change in the behaviour.
Performance-wise, there will potentially be more view updates as explained by the aforementioned example, but assuming no view has a dependency on the ignored property, you will just get a little extra overhead in the getter/setter of the ignored property, because the macro-generated getter/setter records property accesses into the observation registrar. I don't think this will be a noticeable difference.
Upvotes: 1