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

时间:2016-10-02 16:24:14

标签: swift swift3 didset property-observer

我正在对此进行测试,看来如果您更改didSet中的值,则不会再次调用didSet

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

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

3 个答案:

答案 0 :(得分:14)

我还想过,这是不可能的(也许它不是在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
            }
        }
    }
}

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

  

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

答案 1 :(得分:4)

From Apple docs(强调我的):

  

同样,如果你实现了一个didSet观察者,它会传递一个常量   包含旧属性值的参数。你可以命名   参数或使用oldValue的默认参数名称。 如果你   为自己的didSet观察者中的属性赋值,即new   您指定的值将替换刚刚设置的值

因此,在didSet中赋值是正常的,不会触发无限递归。

答案 2 :(得分:1)

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

它没有像我怀疑的那样递归,所以至少这样做。

我可以想到一些情况下,设定者可以接受改变我设定的内容。一个这样的例子可能是一个设置为角度的变量,它会自动标准化为[0, 2π]