在 Swift 中所聲明的屬性包括存儲屬性和計算屬性兩種。其中存儲屬性將會在內存中實際分配地址對屬性進行存儲,而計算屬性則不包括背后的存儲,只是提供 set 和 get 兩種方法。在同一個類型中,屬性觀察和計算屬性是不能同時共存的。也就是說,想在一個屬性定義中同時出現 set 和 willSet 或 didSet 是一件辦不到的事情。計算屬性中我們可以通過改寫 set 中的內容來達到和 willSet 及 didSet 同樣的屬性觀察的目的。如果我們無法改動這個類,又想要通過屬性觀察做一些事情的話,可能就需要子類化這個類,并且重寫它的屬性了。重寫的屬性并不知道父類屬性的具體實現情況,而只從父類屬性中繼承名字和類型,因此在子類的重載屬性中我們是可以對父類的屬性任意地添加屬性觀察的,而不用在意父類中到底是存儲屬性還是計算屬性:
case1
class A {
var number :Int {
get {
print("get")
return 1
}
set {print("set")}
}
}
class B: A {
override var number: Int {
willSet {print("willSet")}
didSet {print("didSet")}
}
}
//調用 number 的 set 方法可以看到工作的順序
let b = B()
b.number = 0
// 輸出
// get // 這個輸出是為了獲取odlValue
// willSet
// set
// didSet
case2
class A {
var number :Int = 0 {
willSet {print("willSet")}
didSet {print("didSet")}
}
}
class B: A {
override var number: Int {
get {
print("get")
return 1
}
set {print("set")}
}
}
//調用 number 的 set 方法可以看到工作的順序
let b = B()
b.number = 0
b.number
// 輸出
// set
// get
case3
class A {
var number :Int = 0 {
willSet {print("willSet")}
didSet {print("didSet")}
}
}
class B: A {
override var number: Int {
get {
print("get")
return super.number
}
set {
print("set")
super.number = newValue
}
}
}
//調用 number 的 set 方法可以看到工作的順序
let b = B()
b.number = 0
b.number
// 輸出
//set
//willSet
//didSet
//get
case4
class A {
var number :Int = 0 {
willSet {print("willSet")}
didSet {print("didSet")}
}
}
class B: A {
override var number: Int {
willSet {print("willSet_b")}
didSet {print("didSet_b")}
}
}
//調用 number 的 set 方法可以看到工作的順序
let b = B()
b.number = 0
b.number
// 輸出
//willSet_b
//willSet
//didSet
//didSet_b
1.當計算屬性被override為存儲屬性時相當于為set方法添加了 willSet 和didSet 方法
2.當存儲屬性被override為計算屬性時會忽略 willSet 和didSet 方法
3.當調用super時,調用順序便可控制