Difference between CurrentValueSubject and @Published
CurrentValueSubject
is a value, a publisher and a subscriber all in one.
Sadly it doesn’t fire objectWillChange.send()
when used inside an ObservableObject.
You can specify an error type.
@Published
is a property wrapper, thus:
- It is not yet supported in top-level code.
- It is not supported in a protocol declaration.
- It can only be used within a class.
@Published
automatically fires objectWillChange.send()
when used inside an ObservableObject.
Xcode will emit a warning if your try to publish to @Published
wrapped property from a background queue. Probably because objectWillChange.send()
must be called from the main thread.
The error type of its publisher is Never
My biggest beef against @Published
is that it can’t behave as a subscriber and setting up Combine pipelines requires additional plumbing compared to a Current Value Subject.
We can declare a @Published
property inside a protocol. Not very pretty...
protocol TestProtocol {
var isEnabled: Bool { get }
var isEnabledPublished: Published<Bool> { get }
var isEnabledPublisher: Published<Bool>.Publisher { get }
}
class Test: ObservableObject, TestProtocol {
@Published var isEnabled: Bool = false
var isEnabledPublished: Published<Bool> { _isEnabled }
var isEnabledPublisher: Published<Bool>.Publisher { $isEnabled }
}
@Published is just a quick way to use CurrentValueSubject a little neater. When I debug one of my apps and look at the type returned by $paramName , it's actually just a CurrentValueSubject:
po self.$books
▿ Publisher
▿ subject : <CurrentValueSubject<Array<Book>, Never>: 0x6000034b8910>
I guess one benefit of using CurrentValueSubject instead of @Published may be to allow you to use the error type?
Note: Despite being a CurrentValueSubject right now I'd never rely on that assumption.