2015-11-23 14 views
14

は、次のことを考えてみましょう:プロトコル拡張の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を導入せずにこれを達成できますか?

つまり、プロトコル拡張の中でプロパティの変更を観察できますか?

+0

関連付けられたプロパティ*を使用する場合は、実際にこれを非常に簡単に行うことができます。最近の記事は、関連するプロパティを作成する方法を正確に示しています。[例](http://stackoverflow.com/documentation/swift/1085/associated-objects/27656/property-in-a-protocol-extension-achieved -using-associated-object#t = 20170128181236289743)これは、これを書いているときにはとても新鮮です。うまくいけば、かなり安定しています。 – Fattie

+0

この質問に関して、このQAで使用されている例は、これを使用できる完全な例です。http://stackoverflow.com/questions/41910120/in-swift3-combine-respondsto-and-calling-in-one-落ちたswoop – Fattie

答えて

24

いいえ、これは明示的に禁止されています。 Extension: Computed Propertiesを参照してください:

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

これが正当なものだった場合、実行の順序については軽視しないでください。たとえば、didSetを追加したいくつかの拡張があり、実際の実装にはdidSetがあったとします。彼らはどんな順序で動くべきですか?これは実装することが不可能であるということを意味するものではありませんが、それがあれば多少驚くかもしれません。

+2

清算をありがとう。しかし、私はそれがもたらすかもしれない**混乱について同意しません。多くの他のプログラミング言語は、この種のダイヤモンド問題を、コンパイルエラーで明示的にするか、宣言の順番から推論するかによって処理します。例えば、競合が発生した場合のScalaは、クラス 'extends'(': ')で宣言された' trait'( 'protocol')に優先順位を与えます。 –

+0

>「どのような順序で実行する必要がありますか?」 本当ですか?私は自然にこの機能を望んでいました。例えば、 など。 新しい顧客ができました。 あなたが気にしている唯一の情報は、彼のユニークな識別子です。 識別子を設定します。 この識別子を設定すると、プロトコルメソッドは必要な顧客に関するすべての情報を取得して取得します。 正しい順序でコードを実行するのは難しくありません すべての関数を手動で呼び出すことに気を配りません。 今のところ、プロトコルと拡張機能を使わずにこの作業を行うのは不便です。 – Ferologics

+0

uuuh heartache :( –

関連する問題