In Swift, does resetting the property inside didSet trigger another didSet?

前端 未结 3 851
南方客
南方客 2020-12-29 07:17

I\'m testing this and it appears that if you change the value within didSet, you do not get another call to didSet.

var x: Int = 0         


        
相关标签:
3条回答
  • 2020-12-29 07:58

    It'll work just fine, but it seems pretty like a pretty bad idea from the standpoint of a consumer of your API.

    It doesn't recurse, the way I suspected it might, so that's good at least.

    I can think of few cases in which it would be acceptable for a setter to change what i'm setting. One such example might be a variable that's set to an angle, which is automatically normalized to be [0, 2π].

    0 讨论(0)
  • 2020-12-29 08:06

    I also thought, that this is not possible (maybe it wasn't in Swift 2), but I tested it and found an example where Apple uses this. (At "Querying and Setting Type Properties")

    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
                }
            }
        }
    }
    

    And below this piece of code, there is the following note:

    In the first of these two checks, the didSet observer sets currentLevel to a different value. This does not, however, cause the observer to be called again.

    0 讨论(0)
  • 2020-12-29 08:11

    From Apple docs (emphasis mine):

    Similarly, if you implement a didSet observer, it’s passed a constant parameter containing the old property value. You can name the parameter or use the default parameter name of oldValue. If you assign a value to a property within its own didSet observer, the new value that you assign replaces the one that was just set.

    So, assigning a value in didSet is officially OK and won't trigger an infinite recursion.

    0 讨论(0)
提交回复
热议问题