24

didSet()初期化コンテキストの外で関数を呼び出さずに、Swift でプロパティの値を設定するにはどうすればよいですか? noside()以下のコードは、クラスの関数内でこれを達成するための失敗した実験でした

class Test
{
    var toggle : Bool = 0
    var hoodwink : Int = 0 {
        didSet(hoodwink)
        {
            toggle = !toggle
        }
    }

// failed attempt to set without a side effect

    func noside(newValue : Int)
    {
        hoodwink = newValue
        println("hoodwink: \(hoodwink) state: \(toggle)")
    }

    func withside(newValue : Int)
    {
        self.hoodwink = newValue
        println("hoodwink: \(hoodwink) state: \(toggle)")
    }
}

自動合成されたプロパティを使用して Objective-C で行うのは非常に簡単です。

副作用あり (setter に存在する場合):

self.hoodwink = newValue;

副作用なし:

_hoodwink = newValue;
4

4 に答える 4

14

これを回避する可能性のあるハックは、didSet をバイパスするセッターを提供することです。

 var dontTriggerObservers:Bool = false
    var selectedIndexPath:NSIndexPath? {
        didSet {
            if(dontTriggerObservers == false){
                //blah blah things to do
            }
        }
    }
    var primitiveSetSelectedIndexPath:NSIndexPath? {
        didSet(indexPath) {
            dontTriggerObservers = true
            selectedIndexPath = indexPath
            dontTriggerObservers = false
        }
    }

醜いが実行可能

于 2014-12-13T19:25:21.647 に答える
10

「副作用を回避する」ためにObjective-Cで行うことは、プロパティのバッキングストアにアクセスすることです-そのインスタンス変数には、デフォルトでアンダースコアが付いています(これは@synthesizeディレクティブを使用して変更できます)。

ただし、Swift 言語の設計者は、プロパティのバッキング変数にアクセスできないように細心の注意を払ったようです。本によると、

Objective-C を使用した経験がある場合は、クラス インスタンスの一部として値と参照を格納する 2 つの方法が提供されていることをご存知かもしれません。プロパティに加えて、インスタンス変数をプロパティに格納された値のバッキング ストアとして使用できます。

Swift は、これらの概念を単一のプロパティ宣言に統合します。Swift プロパティには対応するインスタンス変数がなく、プロパティのバッキング ストアには直接アクセスできません。(強調は私です)

もちろん、これはリフレクションを使用するのではなく、「通常の言語」手段を使用する場合にのみ適用されます。読みやすさを犠牲にして、この制限を回避する方法を提供する可能性があります。

于 2014-08-19T23:06:19.297 に答える