[Pitch] Observation

That is from the #Future Directions section (it is placed there since we need to make a few alterations to the type wrapper proposal to wire this all together). The type wrapper DefaultObservable gets applied to the protocol. This means that any adopter (by default) will be wrapped up in a type wrapper. This means that all field access to any stored item is funneled into that type wrapper instance.

Lets say you have an observable defined as such:

final class MyModel: Observable {
  var name: String = "test"
  init() { }
}

The type wrapper effectively transforms this to:

final class MyModel: Observable {
  struct $Storage {
    var name: String
  }

  var storage: DefaultObservable<Self, $Storage>

  var name: String {
    get {
      storage[wrappedSelf: self, propertyKeyPath: \MyModel.name, storageKeyPath: \$Storage.name]
    }
    set {
      storage[wrappedSelf: self, propertyKeyPath: \MyModel.name, storageKeyPath: \$Storage.name] = newValue
    }
  }
  init() {
    storage = DefaultObservable(for: Self.self, storage: Storage(name: ""))
  }
}

The DefaultObservable then has an ivar of both the $Storage and the ObservationList. So it can manage the access and fetching stuff out of the storage as well as telling the observation list when things are set.

5 Likes