屬性

屬性

本節(jié)內(nèi)容包括:

  • 存儲屬性
  • 計算屬性
  • 屬性觀察器
  • 全局變量和局部變量
  • 類型屬性

存儲屬性

簡單來說届案,一個存儲屬性就是存儲在特定類或結(jié)構(gòu)體的實例里的一個常量或變量秸仙,存儲屬性可以是變量存儲屬性(用關(guān)鍵字var定義)鸟缕,也可以是常量存儲屬性(用關(guān)鍵字let定義)瘫筐。

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}

常量和存儲屬性

如果創(chuàng)建了一個結(jié)構(gòu)體的實例并賦值給一個常量矩桂,則無法修改實例的任何屬性软族,即使定義了變量存儲屬性:

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// 該區(qū)間表示整數(shù)0添谊,1财喳,2,3
rangeOfFourItems.firstValue = 6
// 盡管 firstValue 是個變量屬性碉钠,這里還是會報錯

因為rangeOfFourItems聲明成了常量(用let關(guān)鍵字)纲缓,即使firstValue是一個變量屬性,也無法再修改它了喊废。

這種行為是由于結(jié)構(gòu)體(struct)屬于值類型祝高。當(dāng)值類型的實例被聲明為常量的時候,它的所有屬性也就成了常量污筷。

屬于引用類型的類(class)則不一樣工闺,把一個引用類型的實例賦給一個常量后乍赫,仍然可以修改實例的變量屬性。

延遲存儲屬性

延遲存儲屬性是指當(dāng)?shù)谝淮伪徽{(diào)用的時候才會計算其初始值的屬性陆蟆。在屬性聲明前使用lazy來標(biāo)示一個延遲存儲屬性雷厂。

注意:
必須將延遲存儲屬性聲明成變量(使用var關(guān)鍵字),因為屬性的值在實例構(gòu)造完成之前可能無法得到叠殷。而常量屬性在構(gòu)造過程完成之前必須要有初始值改鲫,因此無法聲明成延遲屬性。

存儲屬性和實例變量

Swift 中的屬性沒有對應(yīng)的實例變量林束,屬性的后端存儲也無法直接訪問像棘。這就避免了不同場景下訪問方式的困擾,同時也將屬性的定義簡化成一個語句壶冒。 一個類型中屬性的全部信息——包括命名缕题、類型和內(nèi)存管理特征——都在唯一一個地方(類型定義中)定義。

計算屬性

除存儲屬性外胖腾,類烟零、結(jié)構(gòu)體和枚舉可以定義計算屬性,計算屬性不直接存儲值咸作,而是提供一個 getter 來獲取值锨阿,一個可選的 setter 來間接設(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()
    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) {
        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)”

squarecenter屬性可以通過點運算符(square.center)來訪問性宏,這會調(diào)用 getter來獲取屬性的值群井。跟直接返回已經(jīng)存在的值不同,getter 實際上通過計算然后返回一個新的Point來表示square的中心點毫胜。如代碼所示书斜,它正確返回了中心點(5, 5)。

center屬性之后被設(shè)置了一個新的值(15, 15)酵使,表示向右上方移動正方形到如圖所示橙色正方形的位置荐吉。設(shè)置屬性center的值會調(diào)用 setter 來修改屬性originxy的值,從而實現(xiàn)移動正方形到新的位置口渔。

只讀計算屬性

只有 getter 沒有 setter 的計算屬性就是只讀計算屬性样屠。只讀計算屬性總是返回一個值,可以通過點運算符訪問缺脉,但不能設(shè)置新的值痪欲。

注意:
必須使用var關(guān)鍵字定義計算屬性,包括只讀計算屬性攻礼,因為它們的值不是固定的业踢。let關(guān)鍵字只用來聲明常量屬性,表示初始化后再也無法修改的值礁扮。

屬性觀察器

屬性觀察器監(jiān)控和響應(yīng)屬性值的變化知举,每次屬性被設(shè)置值的時候都會調(diào)用屬性觀察器瞬沦,甚至新的值和現(xiàn)在的值相同的時候也不例外。
可以為除了延遲存儲屬性之外的其他存儲屬性添加屬性觀察器雇锡,也可以通過重載屬性的方式為繼承的屬性(包括存儲屬性和計算屬性)添加屬性觀察器逛钻。

注意:
不需要為無法重載的計算屬性添加屬性觀察器,因為可以通過 setter 直接監(jiān)控和響應(yīng)值的變化锰提。

可以為屬性添加如下的一個或全部觀察器:

  • willSet在設(shè)置新的值之前調(diào)用
  • didSet在新的值被設(shè)置之后立即調(diào)用

注意:
willSet和didSet觀察器在屬性初始化過程中不會被調(diào)用曙痘,它們只會當(dāng)屬性的值在初始化之外的地方被設(shè)置時被調(diào)用。
如果在didSet觀察器里為屬性賦值欲账,這個值會替換觀察器之前設(shè)置的值屡江。

全局變量和局部變量

計算屬性和屬性觀察器所描述的模式也可以用于全局變量和局部變量,全局變量是在函數(shù)赛不、方法、閉包或任何類型之外定義的變量罢洲,局部變量是在函數(shù)踢故、方法或閉包內(nèi)部定義的變量。

前面章節(jié)提到的全局或局部變量都屬于存儲型變量惹苗,跟存儲屬性類似殿较,它提供特定類型的存儲空間,并允許讀取和寫入桩蓉。

另外淋纲,在全局或局部范圍都可以定義計算型變量和為存儲型變量定義觀察器,計算型變量跟計算屬性一樣院究,返回一個計算的值而不是存儲值洽瞬,聲明格式也完全一樣。

注意:
全局的常量或變量都是延遲計算的业汰,跟延遲存儲屬性相似伙窃,不同的地方在于,全局的常量或變量不需要標(biāo)記lazy特性样漆。
局部范圍的常量或變量不會延遲計算为障。

類型屬性

實例的屬性屬于一個特定類型實例,每次類型實例化后都擁有自己的一套屬性值放祟,實例之間的屬性相互獨立鳍怨。

也可以為類型本身定義屬性,不管類型有多少個實例跪妥,這些屬性都只有唯一一份鞋喇。這種屬性就是類型屬性。

類型屬性用于定義特定類型所有實例共享的數(shù)據(jù)骗奖,比如所有實例都能用的一個常量(就像 C 語言中的靜態(tài)常量)确徙,或者所有實例都能訪問的一個變量(就像 C 語言中的靜態(tài)變量)醒串。

對于值類型(指結(jié)構(gòu)體和枚舉)可以定義存儲型和計算型類型屬性,對于類(class)則只能定義計算型類型屬性鄙皇。

值類型的存儲型類型屬性可以是變量或常量芜赌,計算型類型屬性跟實例的計算屬性一樣定義成變量屬性。

注意:
跟實例的存儲屬性不同伴逸,必須給存儲型類型屬性指定默認(rèn)值缠沈,因為類型本身無法在初始化過程中使用構(gòu)造器給類型屬性賦值。

類型屬性語法

在 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 值
    }
}

獲取和設(shè)置類型屬性的值

跟實例的屬性一樣,類型屬性的訪問也是通過點運算符來進行官紫,但是肛宋,類型屬性是通過類型本身來獲取和設(shè)置,而不是通過實例束世。

println(SomeClass.computedTypeProperty)
// 輸出 "42"

println(SomeStructure.storedTypeProperty)
// 輸出 "Some value."
SomeStructure.storedTypeProperty = "Another value."
println(SomeStructure.storedTypeProperty)
// 輸出 "Another value.”
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酝陈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子毁涉,更是在濱河造成了極大的恐慌沉帮,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贫堰,死亡現(xiàn)場離奇詭異穆壕,居然都是意外死亡,警方通過查閱死者的電腦和手機严嗜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門粱檀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人漫玄,你說我怎么就攤上這事茄蚯。” “怎么了睦优?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵渗常,是天一觀的道長。 經(jīng)常有香客問我汗盘,道長皱碘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任隐孽,我火速辦了婚禮癌椿,結(jié)果婚禮上健蕊,老公的妹妹穿的比我還像新娘。我一直安慰自己踢俄,他們只是感情好缩功,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著都办,像睡著了一般嫡锌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上琳钉,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天势木,我揣著相機與錄音,去河邊找鬼歌懒。 笑死啦桌,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的歼培。 我是一名探鬼主播震蒋,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼躲庄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钾虐,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤噪窘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后效扫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倔监,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年菌仁,在試婚紗的時候發(fā)現(xiàn)自己被綠了浩习。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡济丘,死狀恐怖谱秽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情摹迷,我是刑警寧澤疟赊,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站峡碉,受9級特大地震影響近哟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鲫寄,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一吉执、第九天 我趴在偏房一處隱蔽的房頂上張望疯淫。 院中可真熱鬧,春花似錦戳玫、人聲如沸熙掺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽适掰。三九已至,卻和暖如春荠列,著一層夾襖步出監(jiān)牢的瞬間类浪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工肌似, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留费就,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓川队,卻偏偏與公主長得像力细,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子固额,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容