Swift 擁有類似 C# 的屬性聲明語(yǔ)法:
var foo : int {
get { return getFoo() }
set { setFoo(newValue) }
}
但是,Swift 還另有 willSet 和 didSet 行為。它們分別在調(diào)用 setter 之前和之后被調(diào)用。那它們存在的意義是什么?畢竟考慮到在 setter 里可以寫(xiě)出完全相同的代碼。
其實(shí)關(guān)鍵在于,有時(shí)候我們需要存儲(chǔ)屬性時(shí)自動(dòng)進(jìn)行某些行為,例如通知其它對(duì)象,這個(gè)屬性被改變了。如果只有 get/set,就需要另一個(gè)字段來(lái)保存改動(dòng)之前的值。借助 willSet 和 didSet,值被修改時(shí)進(jìn)行的行為就不需要額外的字段了。例如,在這個(gè)例子中:
class Foo {
var myProperty: Int = 0 {
didSet {
print("myProperty 的值從 \(oldValue) 更改為 \(myProperty)")
}
}
}
每當(dāng) myProperty 被修改時(shí)都會(huì)輸出舊的值和新的值。但如果只有 getter 和 setter,就需要這樣做:
class Foo {
var myPropertyValue: Int = 0
var myProperty: Int {
get { return myPropertyValue }
set {
print("myProperty 的值從 \(myPropertyValue) 更改為 \(myProperty)")
myPropertyValue = newValue
}
}
}
所以 willSet 和 didSet 可以節(jié)省幾行代碼,并且精簡(jiǎn)了字段列表。
另外注意:根據(jù)蘋(píng)果的注釋,在初始化方法中設(shè)置屬性不會(huì)調(diào)用 willSet 和 didSet:willSet and didSet observers are not called when a property is first initialized. They are only called when the property’s value is set outside of an initialization context.