Swift Peoperty
Swift中有下列幾種屬性
- 存儲屬性(Stored properties):存儲實例的常量和變量,與類、結(jié)構(gòu)體赃承、枚舉的實例相關(guān)
- 計算屬性(Computed properties):通過某種方式計算出來的屬性毒租,只與類、結(jié)構(gòu)體的實例相關(guān)衰伯,枚舉沒有計算屬性
- 類型屬性(type properties):與類型自身相關(guān)
存儲屬性
存儲屬性是最簡單的屬性铡羡,它作為類或結(jié)構(gòu)體實例的一部分,用于存儲常量和變量
關(guān)于存儲屬性意鲸,有以下幾點:
- 我們可以給存儲屬性提供一個默認值烦周,也可以在初始化方法中對其進行初始化,即使是常量型屬性怎顾,也可以這樣做读慎。
- 如果創(chuàng)建一個常量結(jié)構(gòu)體實例,我們不能修改該實例的變量型存儲屬性槐雾。這是因為結(jié)構(gòu)體是值類型夭委,當一個值類型的實例標記為常量時,它的所有屬性也是常量募强。由于類是引用類型株灸,所以該條不適用于類類型崇摄。
- 如果我們希望屬性在使用到的時候再初始化,則可以使用懶惰存儲屬性(lazy stored property慌烧,使用修飾符@lazy)配猫。懶惰存儲屬性總是應(yīng)該定義為變量,因為常量型屬性總需要在初始化方法完成之前初始化杏死。
- 與Objective-C不同的是泵肄,Swift中的屬性不需要一個與之對應(yīng)的成員變量,我們不能直接訪問屬性的后備存儲(backing store)淑翼。這種方式避免了混淆不同上下文環(huán)境下對值的訪問腐巢,并將屬性簡化為單一、明確的聲明玄括。
struct FixedLengthRange {
var firstValue: Int //變量存儲屬性
let length: Int //常量存儲屬性
}
var item1 = FixedLengthRange(firstValue: 10, length: 10)
let item2 = FixedLengthRange(firstValue: 10, length: 10)
//item2.firstValue = 6 // 錯誤:不能修改常量結(jié)構(gòu)體實例的存儲屬性
計算屬性
計算屬性并不存儲實際的值冯丙,而是提供一個getter和一個可選的[ setter來間接獲取和設(shè)置其它屬性 ]。
關(guān)于計算屬性遭京,有以下幾點:
- 如果計算屬性的setter沒有定義一個新值的變量名胃惜,則默認為newValue
- 如果只提供getter,而不提供setter哪雕,則該計算屬性為只讀屬性
- 我們只能聲明變量型只讀屬性船殉,因為它們的值不是固定的
- 如果計算屬性是只讀的,則可以不使用get{}
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center:Point { // 計算屬性
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set(newCenter) { // 若不提供新值變量名斯嚎,則默認為newValue
origin.x = newCenter.x - size.width / 2
origin.y = newCenter.y - size.height / 2
}
}
var maxX:Float { // 只讀屬性利虫,省略get{}
return Float(origin.x) + Float(size.width)
}
}
var square = Rect(origin:Point(x: 0.0, y: 0.0), size:Size(width:100, height:100))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y:15.0)
square.maxX
類型屬性
類型屬性是與類型相關(guān)聯(lián)的,而不是與類型的實例相關(guān)聯(lián)堡僻】繁梗— 與類型相關(guān)不與對象相關(guān)對于某一類型(
class
)的所有實例,類型(class
)屬性都只有一份拷貝钉疫。對于值類型(struct
)硼讽,我們可以定義存儲類型屬性和計算類型屬性。對于類(class
)牲阁,我們只能定義計算類型(setter
)屬性固阁。和實例屬性不同的是,我們總是需要給存儲類型(getter
)屬性一個默認值咨油。這是因為類型沒有初始化方法來初始化類型屬性您炉。類型屬性的訪問和設(shè)置與實例屬性一樣柒爵,不一樣的是役电,類型屬性通過類型來獲取和設(shè)置,而不是類型的實例
關(guān)鍵字 : class static
struct AudioChannel {
static let threaholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel:Int = 0 {
didSet{
if currentLevel > AudioChannel.threaholdLevel {
currentLevel = AudioChannel.threaholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}
var leftChannel = AudioChannel()
var rightChannel = AudioChannel()
leftChannel.currentLevel = 7
println(leftChannel.currentLevel) // 7
println(AudioChannel.maxInputLevelForAllChannels) // 7
rightChannel.currentLevel = 11
println(rightChannel.currentLevel) // 10
屬性觀察者
屬性觀察者用于監(jiān)聽和響應(yīng)屬性值的變化棉胀。在每次設(shè)置屬性值的時候都會調(diào)用屬性觀察者方法法瑟,即使新舊值是一樣的冀膝。我們可以為任何存儲屬性定義屬性觀察者,除了懶惰存儲屬性霎挟。我們同樣可以在子類中給繼承而來的屬性添加觀察者窝剖。
對于計算屬性,我們不需要定義屬性觀察者酥夭,因為我們可以在計算屬性的setter中直接觀察并響應(yīng)這種值的變化。
我們通過設(shè)置以下觀察方法來定義觀察者
- willSet:在屬性值被存儲之前設(shè)置。此時新屬性值作為一個常量參數(shù)被傳入啰扛。該參數(shù)名默認為newValue璧坟,我們可以自己定義該參數(shù)名
- 在新屬性值被存儲后立即調(diào)用。與willSet相同讶隐,此時傳入的是屬性的舊值起胰,默認參數(shù)名為oldValue
willSet與didSet只有在屬性第一次被設(shè)置時才會調(diào)用,在初始化時巫延,不會去調(diào)用這些監(jiān)聽方法效五。