如果我将属性值设置为与当前设置的值相同的值,是否会调用willSet和didSet?了解何时在这些功能中发生副作用非常重要。
答案 0 :(得分:14)
是的,即使设置为相同的值,也会调用willSet和didSet。我在操场上测试了它:
class Class1 {
var willSetCount = 0
var didSetCount = 0
var var1: String = "A" {
willSet {
willSetCount++
}
didSet {
didSetCount++
}
}
}
let aClass1 = Class1() // {0 0 "A"}
aClass1.var1 = "A" // {1 1 "A"}
aClass1.var1 = "A" // {2 2 "A"}
如果要在设置相同值时防止发生副作用,可以将该值与newValue / oldValue进行比较:
class Class2 {
var willSetCount = 0
var didSetCount = 0
var var1: String = "A" {
willSet {
if newValue != var1 {
willSetCount++
}
}
didSet {
if oldValue != var1 {
didSetCount++
}
}
}
}
let aClass2 = Class2() // {0 0 "A"}
aClass2.var1 = "A" // {0 0 "A"}
aClass2.var1 = "B" // {1 1 "B"}
答案 1 :(得分:7)
是的,确实如此。你可能有一个不符合Equatable协议的类型的属性,然后“相同的值”没有意义。仅在初始化程序中设置值时才会调用willSet
和didSet
。