I think this is not a bug. It's "technically expected" behavior in that @Published
is designed for use with SwiftUI which requires the change to be published during willSet
.
As a consumer of the API, though, it's quite surprising behavior, and can lead to bugs. In my own code I have several places where I subscribe to a @Published
value in a UIViewController
and then DispatchQueue.main.async
so that I can safely use the full updated object.
I find myself wishing that @Published
had a projected value with two publishers on it: willSet
and didSet
.
Then, instead of doing:
// This is so common I made a convenience method
self.subscriptions += self.lessonState.$selection.sinkMain { [weak self] _ in
self?.updateSelection() // Relies on self.lessonState, not just .selection
}
I could do:
self.subscriptions += self.lessonState.$selection.didSet.sink { [weak self] _ in
self?.updateSelection()
}
Which is more explicit, and would not wait for the next run loop.