The ObservableObject
protocol defined by the Combine framework has an objectWillChange
publisher property that lets you know when the properties of this object will change, meaning that, if subscribers to this publisher were to read its value when they get this will change event, they will still read the value before it is changed, what I am trying to understand is:
ObservableObject
after you received the will change event?SwiftUI doesn't know if the ObservableObject
actually changed. SwiftUI trusts you. If you tell it the object will change (by making objectWillChange
emit an output), then SwiftUI assumes that the object changes, and schedules a display update.
I'm not 100% sure why Apple chose objectWillChange
as the signal. At WWDC 2019, the property was in fact didChange
, not objectWillChange
. They changed it while Xcode 11 was still in beta. Perhaps what they do is grab the object's state when objectWillChange
emits, and then later they grab it again when it's time to update the screen, and they somehow compare the values.
As to how to get the object's value after objectWillChange
emits, that's up to you. They way SwiftUI does it is by registering a CFRunLoopObserver
for the .beforeWaiting
activity. When the observer runs, it re-renders any views whose ObservableObject
s have signaled.
Note that if you use a @Published
property to store the value in your ObservableObject
, then you can subscribe to the property's own publisher by using the $
prefix. For example:
class MyObject: ObservableObject {
@Published var value: Int = 0
}
let object = MyObject()
let ticket = object.$value
.sink { print("new value: \($0); old value: \(object.value)") }
object.value = 1
The Published
wrapper publishes the current value when you subcribe, and then publishes the new value each time it changes. But note that it publishes the new value before storing it, as the example code above demonstrates with the following output:
new value: 0; old value: 0
new value: 1; old value: 0
What I did was add to each ObservableObject that I needed to know after changes of
public var objectDidChange = ObservableObjectPublisher()
That you can subscribe to and you manually call .send()
on after everything has changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With