20

これをテストしていますが、 内で値を変更すると、didSet別の呼び出しが行われないようdidSetです。

var x: Int = 0 {
    didSet {
        if x == 9 { x = 10 }
    }
}

これに頼ってもいいですか?それはどこかに文書化されていますか?Swift プログラミング言語のドキュメントには表示されません。

4

3 に答える 3

18

また、これは不可能だと思いました (おそらく Swift 2 ではそうではありませんでした) が、テストしたところ、Apple がこれを使用している例が見つかりました。(「タイプ プロパティのクエリと設定」で)

struct AudioChannel {
    static let thresholdLevel = 10
    static var maxInputLevelForAllChannels = 0
    var currentLevel: Int = 0 {
        didSet {
            if currentLevel > AudioChannel.thresholdLevel {
                // cap the new audio level to the threshold level
                currentLevel = AudioChannel.thresholdLevel
            }
            if currentLevel > AudioChannel.maxInputLevelForAllChannels {
                // store this as the new overall maximum input level
                AudioChannel.maxInputLevelForAllChannels = currentLevel
            }
        }
    }
}

そして、このコードの下に、次のメモがあります。

これら 2 つのチェックの最初のチェックでは、didSet オブザーバーが currentLevel を別の値に設定します。ただし、これによってオブザーバが再度呼び出されることはありません

于 2016-10-02T16:39:37.493 に答える
16

Apple docs から(強調鉱山):

同様に、didSet オブザーバーを実装すると、古いプロパティ値を含む定数パラメーターが渡されます。パラメーターに名前を付けるか、oldValue の既定のパラメーター名を使用できます。独自の didSet オブザーバー内のプロパティに値を割り当てる場合、割り当てた新しい値は、設定されたばかりの値を置き換えます

したがって、didSet に値を代入することは公式には問題なく、無限再帰はトリガーされません。

于 2018-03-08T17:54:01.250 に答える
1

それは問題なく動作しますが、API の消費者の観点からはかなり悪い考えのように思えます。

私が思っていたように再帰しないので、少なくともそれは良いことです。

セッターが設定内容を変更することが許容されるケースはほとんどないと思います。そのような例の 1 つは、角度に設定された変数であり、自動的に に正規化されます[0, 2π]

于 2016-10-02T16:34:13.613 に答える