實例的屬性屬于一個特定類型實例,每次類型實例化后都擁有自己的一套屬性值,實例之間的屬性相互獨立。
也可以為類型本身定義屬性,不管類型有多少個實例,這些屬性都只有唯一一份。這種屬性就是類型屬性。
類型屬性用于定義特定類型所有實例共享的數(shù)據(jù),比如所有實例都能用的一個常量(就像 C 語言中的靜態(tài)常量),或者所有實例都能訪問的一個變量(就像 C 語言中的靜態(tài)變量)。
對于值類型(指結(jié)構(gòu)體和枚舉)可以定義存儲型和計算型類型屬性,對于類(class)則只能定義計算型類型屬性。
值類型的存儲型類型屬性可以是變量或常量,計算型類型屬性跟實例的計算屬性一樣定義成變量屬性。
注意:
跟實例的存儲屬性不同,必須給存儲型類型屬性指定默認(rèn)值,因為類型本身無法在初始化過程中使用構(gòu)造器給類型屬性賦值。
在 C 或 Objective-C 中,靜態(tài)常量和靜態(tài)變量的定義是通過特定類型加上global關(guān)鍵字。在 Swift 編程語言中,類型屬性是作為類型定義的一部分寫在類型最外層的花括號內(nèi),因此它的作用范圍也就在類型支持的范圍內(nèi)。
使用關(guān)鍵字static來定義值類型的類型屬性,關(guān)鍵字class來為類(class)定義類型屬性。下面的例子演示了存儲型和計算型類型屬性的語法:
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
// 這里返回一個 Int 值
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
// 這里返回一個 Int 值
}
}
class SomeClass {
class var computedTypeProperty: Int {
// 這里返回一個 Int 值
}
}
注意:
例子中的計算型類型屬性是只讀的,但也可以定義可讀可寫的計算型類型屬性,跟實例計算屬性的語法類似。
跟實例的屬性一樣,類型屬性的訪問也是通過點運算符來進(jìn)行,但是,類型屬性是通過類型本身來獲取和設(shè)置,而不是通過實例。比如:
println(SomeClass.computedTypeProperty)
// 輸出 "42"
println(SomeStructure.storedTypeProperty)
// 輸出 "Some value."
SomeStructure.storedTypeProperty = "Another value."
println(SomeStructure.storedTypeProperty)
// 輸出 "Another value.”
下面的例子定義了一個結(jié)構(gòu)體,使用兩個存儲型類型屬性來表示多個聲道的聲音電平值,每個聲道有一個 0 到 10 之間的整數(shù)表示聲音電平值。
后面的圖表展示了如何聯(lián)合使用兩個聲道來表示一個立體聲的聲音電平值。當(dāng)聲道的電平值是 0,沒有一個燈會亮;當(dāng)聲道的電平值是 10,所有燈點亮。本圖中,左聲道的電平是 9,右聲道的電平是 7。

上面所描述的聲道模型使用AudioChannel結(jié)構(gòu)體來表示:
struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
didSet {
if currentLevel > AudioChannel.thresholdLevel {
// 將新電平值設(shè)置為閥值
currentLevel = AudioChannel.thresholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
// 存儲當(dāng)前電平值作為新的最大輸入電平
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}
結(jié)構(gòu)AudioChannel定義了 2 個存儲型類型屬性來實現(xiàn)上述功能。第一個是thresholdLevel,表示聲音電平的最大上限閾值,它是一個取值為 10 的常量,對所有實例都可見,如果聲音電平高于 10,則取最大上限值 10(見后面描述)。
第二個類型屬性是變量存儲型屬性maxInputLevelForAllChannels,它用來表示所有AudioChannel實例的電平值的最大值,初始值是 0。
AudioChannel也定義了一個名為currentLevel的實例存儲屬性,表示當(dāng)前聲道現(xiàn)在的電平值,取值為 0 到 10。
屬性currentLevel包含didSet屬性監(jiān)視器來檢查每次新設(shè)置后的屬性值,有如下兩個檢查:
currentLevel的新值大于允許的閾值thresholdLevel,屬性監(jiān)視器將currentLevel的值限定為閾值thresholdLevel。currentLevel值大于任何之前任意AudioChannel實例中的值,屬性監(jiān)視器將新值保存在靜態(tài)屬性maxInputLevelForAllChannels中。
注意:
在第一個檢查過程中,didSet屬性監(jiān)視器將currentLevel設(shè)置成了不同的值,但這時不會再次調(diào)用屬性監(jiān)視器。