Actually that should be unrelated. IIRC Published always emitted the latest value through its publisher.
You can imagine the internals to be more like this:
set {
// will set
outerSelf.objectWillChange.send()
// did set that pushes the value through the publisher
outerSelf[keyPath: wrapperKeyPath].storage = newValue
}
But the question is, where it's emitted, if you access the value itself, will it be the same as the emitted value? (According to the example above, no.) If not, should it be?
But now I'm curious because I'm struggling to understand why receiving on the main queue would alter that behavior? I think I need to re-read that thread.
Are you testing it with a beta device like mentioned in the thread? If not then it works because internally it still uses async which causes the publisher to emit after the property is truly set. However this is still not didSet semantic.
Which OS do you target in Playground? If it‘s macOS then you also need latest Catalina beta as the framework is part of the OS. On the other hand if it‘s iOS then it should use the framework version from the sim that would have the new behavior.
The last output is completely unexpected.
Can you also try DispatchQueue.main as the scheduler?
I'd say it's quit expected. The events are rescheduled to the future (next runloop), after the last line execute.
It will be easier to understand:
let s = t.valuePublisher
.receive(on: RunLoop.main)
.sink { value in
print("closure value: \(value)")
print("object value: \(t.value)")
}
t.value = 42
print("set value to 42")
t.value = 14
print("set value to 14")
Output:
set value to 42
set value to 14
// next runloop, perform queued tasks one by one
closure value: 0
object value: 14
closure value: 42
object value: 14
closure value: 14
object value: 14