2016-10-02 5 views
8

私はこれをテストしています。didSetの値を変更すると、didSetという別の呼び出しはありません。Swiftでは、内部でプロパティをリセットしていませんか?

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

私はこれに頼ることができますか?それはどこかに文書化されていますか? スウィフトプログラミング言語文書には表示されません。

+0

Xcode 8 Playground(Swift 3)でテストしたところ、同じ結果が得られました。 'didSet'からプロパティを変更した場合、' didSet'は再び__not__されます。 –

+0

「私はこれに頼ることができますか?」はい。 – matt

+0

私は最終的に*最後の*要素をポップするために 'defer'を使用していた配列に' didSet'を実際に持っていました。何が起こったのだろう? 'myArray.isEmpty!= true'の場合にポップしないように、' defer'の中に 'if else'を実行しなければならなかったので、クラッシュしました – Honey

答えて

10

私はこれも可能ではないと考えましたが(Swift 2ではそうでなかったかもしれませんが)、私はそれをテストして、Appleがこれを使用しているan exampleを見つけました。 (「クエリとタイププロパティの設定」で)

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を設定し、異なる値。 これはではありませんが、は再びオブザーバを呼び出す原因となりますです。

+0

これはSwift 4では適用されなくなり、ループを引き起こします。 – thedeveloper3124

+3

@ thedeveloper3124私はSwift 4でテストしましたが、それでも動作します。 – thislooksfun

1

これはうまくいくはずですが、APIのコンシューマの立場から見るとかなり悪い考えです。

私はそれが疑わしい方法を再発しないので、少なくともそれは良いです。

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

+0

Swift 3でこの変更を行いましたか? Swift 2では、再帰呼び出しが実際に行われていたことを覚えています。 –

+0

私の場合は、倍精度浮動小数点値を他の値に最も近い値に丸めます。あらかじめ設定された値を設定しないと、アプリをクラッシュさせる価値はないようです。 –

0

From Apple docs(強調鉱山):あなたはdidSetオブザーバを実装する場合

同様に、それは古いプロパティ値を含む一定の パラメータを渡されています。 パラメーターを指定するか、oldValueのデフォルトパラメーター名を使用できます。 独自のdidSetオブザーバ内のプロパティに値を割り当てると、割り当てられた新しい 値が、ちょうどに設定された値に置き換えられます。

したがって、didSetに値を代入するのは正式にはOKであり、無限再帰をトリガーしません。

関連する問題