Observable Macro and subclasses

During development we saw that we can have a parent class that is annotated with the @observable macro, we can subclass it and that would require also the macro if there are items we need to observe there too! is this the intended behavior or are we doing something wrong?

@observable open class Service {
  var val: Int
}

@observable final class FinalService: Service {
  var str: String
}

1- Is subclassing an @Observable macroed class okay? from my basic understanding how its compiled, the compiler is smart enough to know its alright to have the macro on both the parent and the child.

2- Would it be better to simply append the @Observable on the child only?

This is from the swift evolution:

Subclasses
Developers can create Observable subclasses of either observable or non-observable types. Only the properties of a type that implements the Observable tracking requirements will be observed. That is, when working with an observable subclass of a non-observable type, the superclass's stored properties will not be tracked under observation.

an attached macro changes the code within the block it's applied to.

In Observable's case, it's rewriting your stored properties to have accessors that inform the observation registrar of their changes.

That means that if you don't attach it to the parent, the parent's properties won't be observable, and if you don't attach it to the child, the child's properties won't be observable.

If you're using Xcode, you can right click and expand the macro to see exactly what it did.

Observable also adds a private observation registrar property. I guess it's fine for the child to end up with two registrars? That's the bit I'm least sure of.

2 Likes

That is perfectly ok. The one tricky part is that keypaths are not equal from the child and superclass of the same thing - e.g. \MyClass.someKeyPath != \MySuperClass.someKeyPath which does put a wrinkle in some things...

1 Like

Ah perfect! so as long as we arent overriding a property then all is good