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

Rob*_*b N 14 swift didset swift3 property-observer

我正在对此进行测试,看起来如果你改变其中的值didSet,你就不会再接到另一个电话了didSet.

var x: Int = 0 {
    didSet {
        if x == 9 { x = 10 }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Fel*_*SFD 14

我也想过,这是不可能的(也许它不是在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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这段代码下面,有以下注释:

在这两个检查的第一个中,didSet观察器将currentLevel设置为不同的值.但是,这不会导致再次调用观察者.

  • @ thedeveloper3124我刚刚在Swift 4中测试过它仍然有效. (6认同)
  • 问题不在于它是否会导致循环。如果您的条件无效,它总是会导致循环。在苹果的情况下,它不会导致循环,因为只有当值为“>”时才会触发迭代 (2认同)

Fre*_*ame 7

从Apple文档(重点是我的):

类似地,如果实现didSet观察器,则将传递一个包含旧属性值的常量参数。您可以命名参数或使用默认参数名称oldValue。如果您在其自己的didSet观察器中为属性分配值,则您分配的新值将替换刚刚设置的值

因此,在didSet中分配值正式是可以的,并且不会触发无限递归。