Swift3.0屬性(Properties)

屬性就是將值和特定的類、結構和枚舉進行關聯。存儲屬性存儲常量(變量)來作為實例的一部分,而計算屬性不是存儲一個值。計算屬性可以用于類、結構體和枚舉,但是存儲屬性只能用于類和結構體。

存儲屬性和計算屬性通常和特定的實例類型進行關聯。但是,屬性也可以作用與類型背身,這樣的屬性成為類型屬性。

另外也可以通過定義屬性觀察期來監控屬性值的改變,從而進行一個自定義的操作。屬性觀察器可以添加到自己定義的存儲屬性上,也可以添加到負累繼承的屬性上。

存儲屬性(Stored Properties)

簡單來說,存儲屬性就是用來存儲特定類或結構體實例中的一個常量(變量)。

可以在定義存儲屬性的時候給定默認值,也可以在構造的過程中設置或者修改存儲屬性的值,甚至是修改常量存儲屬性的值。

Stored Properties??

常量結構體實例的存儲屬性(Stored Properties of Constant Structure Instances)

如果創建了一個結構體的實例并賦值給了一個常量,即使有屬性被聲名為變量也無法修改該實例的任何屬性:


報錯了

這是因為結構體是值類型,當值類型的實例被聲名為常量時,它的所有屬性也都成了常量。
所以如果一個引用類型的實例賦給一個常量后,還是可以修改它的變量屬性,就像類(class)。

延遲存儲屬性(Lazy Stored Properties)

延遲存儲屬性指當第一次被調用的時候才會計算初始值的屬性,在屬性聲名前使用 lazy 關鍵字來標明一個延遲儲存屬性。

必須將延遲存儲屬性聲名為變量(var),因為屬性的初始值可能在實例構造完之后才會創建。但是常量屬性在構造過程中必須要有初始值,所以沒有辦法聲名成延遲屬性。

延遲屬性很有用,當屬性的值依賴于在實例的構造過程結束后才會知道影響值的外部因素時,或者當獲得屬性的初始值需要復雜或大量計算時,可以只在需要的時候計算它:


Lazy Stored Properties??

注意
如果一個被 lazy 標記的屬性,在沒有初始化的時候被多個線程訪問,這種情況下不會保證只被創建一次。

存儲屬性和實例變量(Stored Properties and Instance Variables)

OC中為類實例存儲值和引用提供了兩種方法,除了實例之外還可以使用實例變量作為屬性值的后端存儲。

Swift中將這些概念都統一到屬性中。Swift的屬性沒有對應的實例變量,屬性的后端存儲也不能直接訪問。這樣就能避免了不同場景下訪問方式的困擾,同時也可以把屬性的定義簡化為一個語句。屬性的全部信息——包括命名、類型和內存管理特性——都在唯一一個地方(類型定義中)定義。

計算屬性(Computed Properties)

除了存儲屬性之外,類、結構體和枚舉可以定義計算屬性,這種屬性實際上不能存儲之。但是,會提供 getter 和可選的 setter 方法用來間接存儲其他的屬性和值:


Computed Properties ??

便捷 Setter 聲名(Shorthand Setter Declaration)

如果計算屬性的 setter 沒有定義表示新值的參數名,則可以使用默認名稱 newValue:


Shorthand Setter Declaration ??

只讀計算屬性(Read-Only Computed Properties)

只有 getter 沒有 setter 的計算屬性就是只讀計算屬性。只讀計算屬性總是返回一個值,可以通過點語法訪問,但是不能設置新的值。

注意
只能用 var 來聲名計算屬性,因為計算屬性不是固定的。用 let 只能來定義常量屬性,表示初始化后再也無法修改的值。

只讀計算屬性可以去掉 get 關鍵字和括號:


Read-Only Computed Properties ??

屬性觀察器(Property Observers)

屬性觀察器監控和響應值的變化。每次屬性的值被設置的時候都會調用屬性觀察器,甚至是新的值和當前值相同的時候。

可以給除了延時存儲屬性之外的任何存儲屬性添加屬性觀察器。也可以通過重寫屬性的方式為繼承的屬性(包括存儲屬性和計算屬性)添加屬性觀察器。不必為非重寫的計算屬性添加屬性觀察器,因為可以通過它的 setter 直接監控和響應值的變化。

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

  • willSet 在值被存儲之前被調用。
  • didSet 在新的值被存儲之后立即調用。

willSet 觀察器會將新的值作為常量傳入,在 willSet 的實現代碼中可以為這個參數指定一個名稱,如果不指定,則新的值用 newValue 表示。

相似的,實現 didSet 觀察器用一個常量參數表示舊的值,可以為該參數命名或者使用默認名稱 oldValue 。如果在 didSet 中再次對該值賦值,那么新的值會覆蓋舊的值。

注意
父類的屬性在子類的構造器中被賦值時,它在父類中的 willSet 和 didSet 會被調用,然后才會調用子類的觀察器。在父類初始化方法調用之前,子類給屬性賦值時,觀察器是不會被調用的。

Property Observers ??

注意
如果將屬性用 in-out 的方式傳入函數,willSet 和 didSet 也會調用。這是因為 in-out 參數是拷入拷出模式:就是在函數內部使用的是參數的 copy,函數結束后,又對參數重新賦值。

全局和局部變量(Global and Local Variables)

計算屬性和屬性觀察器所描述的屬性也可以用在全局變量和局部變量中。全局變量是被定義在方法、函數、閉包或任何類型之外定義的變量。局部變量在函數、方法或閉包內部定義的變量。

前面提到的全局或局部變量都是屬于存儲變量,和存儲屬性類似,它為特定類型的值提供存儲空間并允許值的讀寫。

除此之外,也可以在全局或局部范圍定義計算變量和為存儲變量定義觀察器。計算變量和計算屬性一樣,返回一個計算結果而不是返回存儲值,聲名格式也完全一樣。

注意
全局的常量(變量)都是延遲計算的,跟延遲存儲屬性類似,不同的地方在于,全局的常量(變量)不需要 lazy 修飾符。
局部的常量(變量)從不延遲計算。

類型屬性(Type Properties)

實例屬性就是一個特定類型的實例,每次創建一個新的實例,它都會有一套屬于自己的屬性值,并且每個實例之間的屬性都是相互獨立的。

也可以為類型本身定義屬性,所以無論創建了多少個實例,這樣的屬性都只有唯一的一份。這樣的屬性就是類型屬性。

類型屬性就是用來共享某個類型的所有實例的數據,比如所有實例都能用一個常量(像C語言中的靜態常量),或者都能用一個變量(C語言中的靜態變量)

存儲型類型屬性可以是常量或者變量,但是計算型類型屬性只能為變量。

注意
和存儲實例屬性不同,必須給存儲型屬性一個默認值。這是因為在存儲型類型屬性在初始化的時候并沒有構造器為其賦值。
存儲型類型屬性是延遲初始化的,它們只有在第一次被訪問的時候才會初始化。即使它們被多個線程同事訪問,系統也保證只會對其初始化一次,并且不需要 lazy 修飾符。

類型屬性語法(Type Property Syntax)

在C語言和OC中,與某個類型關聯的靜態常量(變量),是作為全局靜態變量定義的。但是在Swift中,類型屬性是作為類型的一部分寫在類型最外層的括號內的,所以它的作用范圍就是類型支持的范圍內。

用 static 關鍵字來定義類型屬性。在為類定義計算型類型屬性時,可以改用 class 關鍵字來支持子類對父類的實現進行重寫:


Type Property Syntax ??

??中的計算型類型屬性是只讀的,但也可以定義可讀寫的計算型類型屬性,跟計算型實例屬性的語法相同。

查詢和設置類型屬性(Querying and Setting Type Properties)

和實例屬性一樣,類型屬性也是通過點語法來訪問的。但是類型屬性是通過類型本身進行訪問的,而不是通過實例:


Querying and Setting Type Properties ??

下面有一個??,定義一個結構體來表示音量,每個聲道的音量都是0-10之間的整數:


左聲道音量為9,右聲道音量為7
??1

注意
在第一個檢查過程中,didSet 屬性觀察期將 currentLevel 設置成了不同的值,但是這不會造成屬性觀察期被再次調用。

??2
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Swift語法基礎(五)-- (類和結構體、屬性、方法) 本章將會介紹 類和結構體對比結構體和枚舉是值類型類是引用...
    寒橋閱讀 1,103評論 0 1
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,896評論 1 10
  • 常量與變量使用let來聲明常量,使用var來聲明變量。聲明的同時賦值的話,編譯器會自動推斷類型。值永遠不會被隱式轉...
    莫_名閱讀 467評論 0 1
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,993評論 19 139
  • 潔白的球鞋藍藍的天 清清的河水肩上的蝶 金黃的油菜軟軟的棉 漫漫的時光天真的臉 歌唱的鳥兒翩翩的葉 彎彎的小路遠方...
    清白臉龐閱讀 433評論 4 13