Implementing a protocol default implementation analogous to that of ObservableObject

According the documentation on the ObservableObject protocol:

By default an ObservableObject synthesizes an objectWillChange publisher that emits the changed value before any of its @Published properties changes.

How would one implement such a default implementation with our own protocols? For example, if we were to create a MyCustomObservableObject, how could we use a protocol extension to achieve the same default behavior?

We can’t look at the source because the Combine framework is not (yet?) open source, but we know its default implementation makes var objectWillChange available when ObjectWillChangePublisher is ObservableObjectPublisher.

Most likely, the default implementation of objectWillChange is just a regular publisher that doesn't check for changes itself (eg. by using reflection). Instead, what probably happens is that the @Published property wrapper triggers the objectWillChange of its enclosing instance when its wrapped value changes.

There's a hidden API to access the value in which a property wrapper is defined, which you could use to achieve the same thing β€” check this out: https://www.swiftbysundell.com/articles/accessing-a-swift-property-wrappers-enclosing-instance

3 Likes

Whoa what a find! I guess Swift by Sundell has pretty much everything. I'll be sure to look at the Swift Evolution proposals now for other hidden gems like this one.

You can see a recreation of how the objectWillChange object is automatically synthesised in the OpenCombine framework. Essentially, it relies on ABI stability to know that type metadata must exist in certain memory locations, and stores/retrieves that generated object as appropriate.

In general, I personally wouldn't recommend adopting a pattern like this β€” until the language gets official support for stored properties via protocol extensions. I think SwiftUI does it in bad taste.

1 Like
Terms of Service

Privacy Policy

Cookie Policy