屬性
屬性將值跟特定的類、結(jié)構(gòu)體和枚舉關(guān)聯(lián)。存儲屬性存儲常量或變量作為實例的一部分,而計算屬性計算(不是存儲)一個值。計算屬性可以用于類、結(jié)構(gòu)體和枚舉,存儲屬性只能用于類和結(jié)構(gòu)體。
存儲屬性和計算屬性通常與特定類型的實例關(guān)聯(lián)。但是屬性也可以直接作用于類型本省,這種屬性稱為類型屬性。
另外,還可以定義屬性觀察器來監(jiān)控屬性值的變化,以此來觸發(fā)一個自定義的操作。屬性觀察器可以添加到自己
定義的存儲屬性上,也可以添加到從父類繼承的屬性上。
存儲屬性
簡單來說,一個存儲屬性就是存儲在特定類或結(jié)構(gòu)體的實例里的一個常量或變量。存儲屬性可以是變量存儲屬性(用關(guān)鍵字var定義),也可以是常量存儲屬性(用關(guān)鍵字let定義)
可以在定義存儲屬性的時候指定默認值。也可以在構(gòu)造過程中設(shè)置或者修改存儲屬性的,甚至修改常量存儲屬性的值。
常量結(jié)構(gòu)體的存儲屬性
如果創(chuàng)建了一個結(jié)構(gòu)體的實例并將其賦值給一個常量,則無法修改該實例的任何屬性,即使定義了變量存儲屬性:
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4) // 該區(qū)間表示整數(shù)0,1,2,3rangeOfFourItems.firstValue = 6// 盡管 firstValue 是個變量屬性,這里還是會報錯
因為 rangeOfFourItems 被聲明成了常量(用 let 關(guān)鍵字),即使 firstValue 是一個變量屬性,也無法再修改它 了。
這種行為是由于結(jié)構(gòu)體(struct)屬于值類型。當值類型的實例被聲明為常量的時候,它的所有屬性也就成了常 量。
屬于引用類型的類(class)則不一樣。把一個引用類型的實例賦給一個常量后,仍然可以修改該實例的變量屬 性。
延遲存儲屬性
延遲存儲屬性是指當?shù)谝淮伪徽{(diào)用的時候才會計算其初始值的屬性。在屬性聲明前使用lazy來標示一個延遲存儲屬性。
必須將延遲存儲屬性聲明成變量(使用var關(guān)鍵字),因為屬性的初始值可能在實例構(gòu)造完成之后才會得到。
而常量屬性在構(gòu)造過程完成之前必須要有初始值,因此無法聲明成延遲屬性。
延遲屬性很有用,當屬性的值依賴于在實例的構(gòu)造過程結(jié)束后才會知道具體值的外部因素時,或者當獲得屬性的
初始值需要復雜或大量計算時,可以只在需要的時候計算它。
存儲屬性和實例變量
計算屬性
計算屬性不直接存儲值,而是提供一個getter和一個可選的setter,來間接獲取和設(shè)置其他屬性或變量的值。
只讀計算屬性
只有g(shù)etter 沒有setter的計算屬性就是只讀計算屬性。只讀計算屬性總是返回一個值,可以通過點運算符訪問,但不能設(shè)置新的值。
必須使用var關(guān)鍵字定義計算屬性,包括只讀計算屬性,因為它們的值不是固定的。let關(guān)鍵字只用來聲明常量屬性,表示初始化后再也無法修改的值。
只讀計算屬性的聲明可以去掉get關(guān)鍵字和花括號
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)") // 輸出 "the volume of fourByFiveByTwo is 40.0"
屬性觀察器
屬性觀察器監(jiān)控和響應(yīng)屬性值的變化,每次屬性都被設(shè)置值得時候都會調(diào)用屬性棺材器,甚至新的值和現(xiàn)在的值相同的時候也不例外。
可以為屬性添加如下的一個或全部觀察器: ? 在新的值被設(shè)置之前調(diào)用
第 2 章 Swift 教程 | 164
var
let
get
Cuboid
volume
width height depth volume
Cuboid
width height depth
volume
willSet
} }
只讀計算屬性
只有 getter 沒有 setter 的計算屬性就是只讀計算屬性。只讀計算屬性總是返回一個值,可以通過點運算符訪 問,但不能設(shè)置新的值。
注意:必須使用 關(guān)鍵字定義計算屬性,包括只讀計算屬性,因為它們的值不是固定的。 關(guān)鍵字只用來聲明常 量屬性,表示初始化后再也無法修改的值。
只讀計算屬性的聲明可以去掉 關(guān)鍵字和花括號:
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}}let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0) print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)") // 輸出 "the volume of fourByFiveByTwo is 40.0"
這個例子定義了一個名為 的結(jié)構(gòu)體,表示三維空間的立方體,包含 、 和 屬性。結(jié)構(gòu)
的值毫無意義,因為無法確定修改
willSet didSet 在新的值被設(shè)置之前調(diào)用
? didSet在新的值被設(shè)置之后立即調(diào)用
willSet 觀察器會將新的屬性值作為常量參數(shù)傳入,在 willSet 的實現(xiàn)代碼中可以為這個參數(shù)指定一個名稱,如 果不指定則參數(shù)仍然可用,這時使用默認名稱 newValue 表示。
類似地, didSet 觀察器會將舊的屬性值作為參數(shù)傳入,可以為該參數(shù)命名或者使用默認參數(shù)名 oldValue 。