9

I'm running into an issue where in Combine where I have a boolean @Published property.

When I set it to true, the sink closure is run and I can look at the value being received. It's true. But when I compare it against the actual property that I am observing, they are different.

This bit of code can be simply run in a playground. I'm not sure how this works or why the values would be different

class TestModel {
    @Published var isLoading = false
}

let model = TestModel()

model.$isLoading.sink { (isLoading) in
    if isLoading != model.isLoading {
        print("values NOT same")
    }
}

model.isLoading = true
YichenBman
  • 5,011
  • 8
  • 46
  • 65

1 Answers1

28

@Published publishes the new value before it actually modifies the stored value. This is documented:

When the property changes, publishing occurs in the property’s willSet block, meaning subscribers receive the new value before it’s actually set on the property.

If the @Published property is part of an ObservableObject, it also triggers the enclosing object's objectWillChange publisher before the new value is actually set on the property.

(This answer used to include a disassembly of part of the @Published wrapper, but that is no longer needed because Apple has now documented the behavior.)

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Brilliant stuff. — I wonder if this has something to do with the change from ObservableObject `objectDidChange` to `objectWillChange`. – matt Mar 06 '20 at 23:26
  • Could be. This method is also responsible for posting that notification at address `46251` by calling `Combine.ObservableObjectPublisher.send() -> ()`. – rob mayoff Mar 06 '20 at 23:48
  • 2
    This is by design: https://developer.apple.com/documentation/combine/published "When the property changes, publishing occurs in the property’s **willSet** block, meaning subscribers receive the new value before it’s actually set on the property." – Charlton Provatas Dec 08 '20 at 18:35
  • is it possible to subscribe to changes at the `didSet` stage? – lewis Sep 30 '22 at 17:59
  • 1
    @lewis Not with an `@Published` property. – rob mayoff Sep 30 '22 at 20:57