Is it bug in @Observation makro? Or feature?

Hi everybody!

I try to refactor my old code to new @Observable pattern. And I found strange behaviour when class is subclassed.

First, I have defined protocol:

protocol HasSourcesAndTargets {
    var sources: [String] {get}
    var targets: [String] {get set}
    var name: String {get set}
    var id: UUID {get set}
}

Next base class:

@Observable
class ParentFoo: HasSourcesAndTargets {
    private var _sources = ["Alfa", "Beta"]
    var sources:[String] {
        _sources
    }
    var targets: [String] = []
    var name: String = ""
    var id = UUID()
}

When I add new subclass

@Observable
class ChildFoo: ParentyFoo {
    private var _childSources = ["Theta", "Gamma"]
    override var sources: [String] {
        _childSources
    }
    override var targets:[String] = []
}

I got a @ObservationTracked macro error on targets in ChildFoo -
Property does not override any property from its superclass
and In expansion of macro 'ObservationTracked' here on var targets

@ObservationIgnored private
    override  var _targets: [String] = []

or
Overriding declaration requires an 'override' keyword if I remove override from var targets definition. (of course)

Any override var in ChildFoo generates similar error.

Is mixing @Observable, subclassing and protocols somehow possible? Or should I find another way to deal with it?

INVASTIGATION:

When I expanded macros, I found added code:

@ObservationIgnored **private**

override var _targets: [String] = []   //Error is here
{
    @storageRestrictions(initializes: _targets)
    init(initialValue) {
      _targets = initialValue
    }

    get {
      access(keyPath: \.targets)
      return _targets
    }

    set {
      withMutation(keyPath: \.targets) {
        _targets = newValue
      }
    }
}

So, maybe it's a bug in @Observable makro?

When I added in both classes private var whatever compiler said nothing about overriding. Maybe @Obesrvable makro should not copy override to its private (hidden) values?

1 Like