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 {
didSet {
if x == 9 { x = 10 }
}
}
Can I rely on this? Is it documented somewhere? I don't see it in the Swift Programming Language document.
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.
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.
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π]
.
来源:https://stackoverflow.com/questions/39819081/in-swift-does-resetting-the-property-inside-didset-trigger-another-didset