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
sink(receiveCompletion:receiveValue:) takes two closures. The first closure executes when it receives Subscribers. Completion, which is an enumeration that indicates whether the publisher finished normally or failed with an error. The second closure executes when it receives an element from the publisher.
@Published is one of the property wrappers in SwiftUI that allows us to trigger a view redraw whenever changes occur. You can use the wrapper combined with the ObservableObject protocol, but you can also use it within regular classes.
What's a sink? While a complete explanation of Combine, publishers, subscribers, and sinks is beyond the scope of this article, for our purposes here it's probably enough to know that in Combine a sink is the code receives data and completion events or errors from a publisher and deals with them.
Overview. The Combine framework provides a declarative Swift API for processing values over time. These values can represent many kinds of asynchronous events. Combine declares publishers to expose values that can change over time, and subscribers to receive those values from the publishers.
@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.)
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