Is this a bug in @Published?

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.

3 Likes