存儲(chǔ)屬性
最簡(jiǎn)單的情形,作為特定類(lèi)或結(jié)構(gòu)實(shí)例的一部分,存儲(chǔ)屬性存儲(chǔ)著常量或者變量的值。存儲(chǔ)屬性可分為變量存儲(chǔ)屬性(關(guān)鍵字var描述)和常量存儲(chǔ)屬性(關(guān)鍵字let描述)。
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8
常量結(jié)構(gòu)實(shí)例的存儲(chǔ)屬性
如果你創(chuàng)建一個(gè)結(jié)構(gòu)實(shí)例,并將其賦給一個(gè)常量,這個(gè)實(shí)例中的屬性將不可以被改變,即使他們被聲明為變量屬性
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// 該區(qū)間表示整數(shù)0,1,2,3
rangeOfFourItems.firstValue = 6
// 盡管firstValue詩(shī)歌變量屬性,這里還是會(huì)報(bào)錯(cuò)
屬于引用類(lèi)型的類(lèi)(class)則不一樣,把一個(gè)引用類(lèi)型的實(shí)例賦給一個(gè)常量后,仍然可以修改實(shí)例的變量屬性。
延遲存儲(chǔ)屬性
延遲存儲(chǔ)屬性是指當(dāng)?shù)谝淮伪徽{(diào)用的時(shí)候才會(huì)計(jì)算其初始值的屬性。在屬性聲明前使用@lazy 來(lái)標(biāo)示一個(gè)延遲存儲(chǔ)屬性。
class DataImporter {
/*
DataImporter 是一個(gè)將外部文件中的數(shù)據(jù)導(dǎo)入的類(lèi)。
這個(gè)類(lèi)的初始化會(huì)消耗不少時(shí)間。
*/
var fileName = "data.txt"
// 這是??供數(shù)據(jù)導(dǎo)入功能
}
class DataManager {11. @lazy
var importer = DataImporter()
var data = String[]()
// 這是提供數(shù)據(jù)管理功能
}
let manager = DataManager()
manager.data += "Some data"
manager.data += "Some more data"
// DataImporter 實(shí)例的 importer 屬性還沒(méi)有被創(chuàng)建
由于使用了@lazy,importer 屬性只有在第一次被訪問(wèn)的時(shí)候才被創(chuàng)建。比如訪問(wèn)它的屬性fileName 時(shí):
println(manager.importer.fileName)
// DataImporter 實(shí)例的 importer 屬性現(xiàn)在被創(chuàng)建了
// 輸出 "data.txt”
計(jì)算屬性
除存儲(chǔ)屬性外,類(lèi)、結(jié)構(gòu)體和枚舉可以定義計(jì)算屬性,計(jì)算屬性不直接存儲(chǔ)值,而是提供一個(gè) getter 來(lái)獲取值,一個(gè)可選的 setter 來(lái)間接設(shè)置其他屬性或變量的值。
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()
varcenter: Point {
get{
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set(newCenter) {
origin.x = newCenter.x - (size.width / 2)
origin.y = newCenter.y - (size.height / 2)
}
}
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
println("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// 輸出 "square.origin is now at (10.0, 10.0)”
The Swift Programming Language中文版(CocoaChina精校)
屬性監(jiān)視器
屬性監(jiān)視器監(jiān)控和響應(yīng)屬性值的變化,每次屬性被設(shè)置值的時(shí)候都會(huì)調(diào)用屬性監(jiān)視器,甚至新的值和現(xiàn)在的值相同的時(shí)候也不例外。可以為除了延遲存儲(chǔ)屬性之外的其他存儲(chǔ)屬性添加屬性監(jiān)視器,也可以通過(guò)重載屬性的方式為繼承的屬性(包括存儲(chǔ)屬性和計(jì)算屬性)添加屬性監(jiān)視器。
可以為屬性添加如下的一個(gè)或全部監(jiān)視器:
- willSet 在設(shè)置新的值之前調(diào)用。監(jiān)視器會(huì)將新的屬性值作為固定參數(shù)傳入,在 willSet 的實(shí)現(xiàn)代碼中可以為這個(gè)參數(shù)指定一個(gè)名稱(chēng),如果不指定則參數(shù)仍然可用,這時(shí)使用默認(rèn)名稱(chēng) newValue 表示。
- 在新的值被設(shè)置之后立即調(diào)用。監(jiān)視器會(huì)將舊的屬性值作為參數(shù)傳入,可以為該參數(shù)命名或者使用默認(rèn)參數(shù)名 oldValue。
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
println("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
println("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps