在 Swift 中,重置 didSet 中的 属性 是否会触发另一个 didSet?

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

我正在对此进行测试,如果您更改 didSet 内的值,您似乎不会再调用 didSet

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

我可以依靠这个吗?它记录在某处吗?我在 Swift 编程语言 文档中没有看到它。

它会工作得很好,但从 API 的消费者的角度来看,这似乎是一个非常糟糕的主意。

它不会像我怀疑的那样递归,所以至少这很好。

我能想到少数情况下 setter 可以接受更改我的设置。一个这样的例子可能是一个设置为角度的变量,它会自动归一化为 [0, 2π].

我也认为,这是不可能的(也许 Swift 2 中没有),但我对其进行了测试,发现 an example Apple 使用了它。 (在 "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
            }
        }
    }
}

并且在这段代码的下方,有如下注释:

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.

From Apple docs(强调我的):

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.

所以,在didSet中赋值是正式的,不会触发无限递归。