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中可以有相同的代码,它们的目的是什么?
当前回答
我不懂c#,但稍微猜一下,我想我懂了
foo : int {
get { return getFoo(); }
set { setFoo(newValue); }
}
所做的事。它看起来非常类似于你在Swift中拥有的,但它不一样:在Swift中你没有getFoo和setFoo。这不是一个小的区别:这意味着你没有任何底层存储你的价值。
Swift已经存储和计算了属性。
计算属性有get,也可能有set(如果它是可写的)。但是getter和setter中的代码,如果它们需要实际存储一些数据,就必须在其他属性中完成。没有备份存储。
另一方面,存储属性确实有备份存储。但是它没有get和set。相反,它有willSet和didSet,你可以使用它们来观察变量的变化,并最终触发副作用和/或修改存储的值。对于计算属性,您没有willSet和didSet,并且您不需要它们,因为对于计算属性,您可以使用set中的代码来控制更改。
其他回答
didSet非常方便的一件事是当您使用outlet添加额外配置时。
@IBOutlet weak var loginOrSignupButton: UIButton! {
didSet {
let title = NSLocalizedString("signup_required_button")
loginOrSignupButton.setTitle(title, for: .normal)
loginOrSignupButton.setTitle(title, for: .highlighted)
}
您还可以使用didSet将变量设置为不同的值。这不会像属性指南中所述的那样导致再次调用观察者。例如,当你想限制值如下所示时,它是有用的:
let minValue = 1
var value = 1 {
didSet {
if value < minValue {
value = minValue
}
}
}
value = -10 // value is minValue now.
我不懂c#,但稍微猜一下,我想我懂了
foo : int {
get { return getFoo(); }
set { setFoo(newValue); }
}
所做的事。它看起来非常类似于你在Swift中拥有的,但它不一样:在Swift中你没有getFoo和setFoo。这不是一个小的区别:这意味着你没有任何底层存储你的价值。
Swift已经存储和计算了属性。
计算属性有get,也可能有set(如果它是可写的)。但是getter和setter中的代码,如果它们需要实际存储一些数据,就必须在其他属性中完成。没有备份存储。
另一方面,存储属性确实有备份存储。但是它没有get和set。相反,它有willSet和didSet,你可以使用它们来观察变量的变化,并最终触发副作用和/或修改存储的值。对于计算属性,您没有willSet和didSet,并且您不需要它们,因为对于计算属性,您可以使用set中的代码来控制更改。
Getter和setter有时太笨重,不能仅仅为了观察正确的值变化而实现。通常这需要额外的临时变量处理和额外的检查,如果你写了数百个getter和setter,你会想要避免这些微小的劳动。这些东西是为这种情况准备的。
这些被称为属性观察员:
属性观察员观察并响应属性的变化 价值。每当属性值为时,都会调用属性观察器 设置,即使新值与属性的当前值相同 价值。
摘自:苹果公司《快速编程语言》。“iBooks。https://itun.es/ca/jEUH0.l
我怀疑这是为了允许我们传统上用KVO做的事情,比如与UI元素的数据绑定,或者触发改变属性的副作用,触发同步进程,后台处理,等等。