Swift的属性声明语法与c#非常相似:
var foo: Int {
get { return getFoo() }
set { setFoo(newValue) }
}
但是,它也有willSet和didSet动作。它们分别在调用setter之前和之后调用。考虑到在setter中可以有相同的代码,它们的目的是什么?
Swift的属性声明语法与c#非常相似:
var foo: Int {
get { return getFoo() }
set { setFoo(newValue) }
}
但是,它也有willSet和didSet动作。它们分别在调用setter之前和之后调用。考虑到在setter中可以有相同的代码,它们的目的是什么?
当前回答
请注意 当在委托发生之前在初始化式中设置属性时,不会调用willSet和didSet观察器
其他回答
重点似乎是,有时您需要一个具有自动存储和某些行为的属性,例如通知其他对象该属性刚刚更改。当您只有get/set时,您需要另一个字段来保存该值。使用willSet和didSet,您可以在修改值时采取行动,而不需要另一个字段。例如,在这个例子中:
class Foo {
var myProperty: Int = 0 {
didSet {
print("The value of myProperty changed from \(oldValue) to \(myProperty)")
}
}
}
每次修改myProperty时,都会打印它的旧值和新值。只有getter和setter,我需要这个代替:
class Foo {
var myPropertyValue: Int = 0
var myProperty: Int {
get { return myPropertyValue }
set {
print("The value of myProperty changed from \(myPropertyValue) to \(newValue)")
myPropertyValue = newValue
}
}
}
因此,willSet和didSet代表了两行代码的节省,并且字段列表中的噪音更少。
这些被称为属性观察员:
属性观察员观察并响应属性的变化 价值。每当属性值为时,都会调用属性观察器 设置,即使新值与属性的当前值相同 价值。
摘自:苹果公司《快速编程语言》。“iBooks。https://itun.es/ca/jEUH0.l
我怀疑这是为了允许我们传统上用KVO做的事情,比如与UI元素的数据绑定,或者触发改变属性的副作用,触发同步进程,后台处理,等等。
Getter和setter有时太笨重,不能仅仅为了观察正确的值变化而实现。通常这需要额外的临时变量处理和额外的检查,如果你写了数百个getter和setter,你会想要避免这些微小的劳动。这些东西是为这种情况准备的。
didSet非常方便的一件事是当您使用outlet添加额外配置时。
@IBOutlet weak var loginOrSignupButton: UIButton! {
didSet {
let title = NSLocalizedString("signup_required_button")
loginOrSignupButton.setTitle(title, for: .normal)
loginOrSignupButton.setTitle(title, for: .highlighted)
}
每当属性被赋值时,属性的willSet和didSet观察者。即使新值与当前值相同,也是如此。
注意,willSet需要一个参数名来处理,另一方面,didSet不需要。
在property的值更新后调用didSet观察者。它与旧值进行比较。如果总步数增加了,则打印一条消息以指示已经执行了多少新步数。didSet观察者没有为旧值提供自定义参数名,而是使用默认名称oldValue。