2016-10-04 30 views

答えて

26

Kotlinは、プロパティの変更観察用のビルトインスウィフトスタイルのソリューションを提供していませんが、あなたはまだあなたの目標が何であるかに応じて、いくつかの方法でそれを行うことができます。

  • あなたがプロパティの変更を処理することができますobservable(...)デリゲート(in stdlib)があります。使用例:ここでは

    var foo: String by Delegates.observable("bar") { property, old, new -> 
        println("$property has changed from $old to $new") 
    } 
    

    "bar"プロパティfooの初期値であり、プロパティが割り当てられた後、ラムダは、あなたが防ぐことができますchanges.Thereのもvetoable(...) delegateを観察することができ、たびに呼び出されます変化。

  • あなたは、実際の値の変更後/前に任意のコードを実行するプロパティのcustom setterを使用することができます。

    var foo: String = "foo" 
        set(value: String) { 
         baz.prepareToDoTheThing() 
         field = value 
         baz.doTheThing() 
        } 
    

    @KirillRakhmanに述べたように、それがメソッド呼び出しにオーバーヘッドを導入しないため、この解決策は非常に効率的であり、そしていくつかのプロパティの場合には、コードは少し重複しています。

  • 一般的には、明示的getValue(...)setValue(...)関数でプロパティの振る舞いを提供する、property delegate自分自身を実装することができます。

    あなたがプロパティの変更(のようなobservable以上vetoable)の例を観察し、デリゲートを実装することができます​​抽象クラスを使用、あなたのタスクを簡素化するために:あなたの便宜のために

    var foo: String by object : ObservableProperty<String>("bar") { 
        override fun beforeChange(property: KProperty<*>, oldValue: String, newValue: String): Boolean { 
         baz.prepareToDoTheThing() 
         return true // return false if you don't want the change 
        } 
    
        override fun afterChange(property: KProperty<*>, oldValue: String, newValue: String) { 
         baz.doTheThing() 
        } 
    } 
    

    を、あなたが作成する関数を書くことができますデリゲートオブジェクト:

    fun <T> observing(initialValue: T, 
            willSet:() -> Unit = { }, 
            didSet:() -> Unit = { } 
    ) = object : ObservableProperty<T>(initialValue) { 
        override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = 
          true.apply { willSet() } 
    
        override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = didSet() 
    } 
    

    は、次に、あなただけの彼らのためにwillSetdidSetthe default argumentとしてそれにラムダを渡します{ })。使用法:いずれの場合で

    var foo: String by observing("bar", willSet = { 
        baz.prepareToDoTheThing() 
    }, didSet = { 
        baz.doTheThing() 
    }) 
    
    var baq: String by observing("bar", didSet = { println(baq) }) 
    

、それは可能性が無限再帰に陥ると変化を観察するコードが再びプロパティを設定していないことを確認するためにあなた次第です、または他のあなたがチェックかもしれませんsetterが再帰的に呼び出されるかどうかは、観測コード内で確認してください。

+0

驚いたことに、この2番目のアプローチは、私が質問している間に構築していた回避策です。 :D – Supuhstar

+1

@ Suuphstar、うれしいことにあなたはうれしいです。:) – hotkey

+2

@hotkeyそれを実装する最も効率的な方法であるので、カスタムセッターをちょっと詳しく説明する必要があります。 –

関連する問題