web-dev-qa-db-ja.com

Swiftプロトコル拡張のプロパティオブザーバー?

以下を検討してください。

protocol ViewControllable: class {
  typealias VM: ViewModellable
  var vm: VM! { get }
  func bind()
}

extension ViewControllable {
  var vm: VM! {
    didSet {
      bind()
    }
  }
}

vmプロパティを監視し、注入されるたびにbindを呼び出そうとしています。しかし、これはエラーでコンパイルできません:

拡張機能には、保存されたプロパティを含めることはできません

プロトコルはプロパティをstoredまたはcomputedに強制できないため、これは理にかなっています。

これは、class inheritanceを導入せずに達成できますか?

言い換えれば、プロトコル拡張内のプロパティの変更を観察できますか?

22
Daniel Shin

いいえ、これは明示的に禁止されています。 拡張:計算されたプロパティ を参照してください:

拡張機能は、新しい計算プロパティを追加できますが、保存されたプロパティを追加したり、既存のプロパティにプロパティオブザーバーを追加したりすることはできません。

これが合法である場合、実行の順序について重要な混乱が生じることを覚えておいてください。 didSetを追加した拡張機能がいくつかあり、実際の実装にもdidSetがあったとします。彼らはどのような順序で実行する必要がありますか?これは、実装が不可能であることを意味するわけではありませんが、それがあったとしたら、いくぶん驚くかもしれません。

30
Rob Napier