iOS開發Swift篇—(九)屬性


iOS開發Swift篇—(九)屬性

一、類的定義

Swift與Objective-C定義類的區別

Objective-C:一般需要2個文件,1個.h聲明文件和1個.m實現文件

Swift:只需要1個.swift文件

Swift中類的定義格式

1 class 類名  {
2     // ... 屬性和方法
3 }

 

二、屬性

1.什么是屬性

  Swift中的屬性(Properties),就類似於其他面向對象語言中的成員變量

2.屬性的分類

按照官方文檔的說明,屬性可以分為以下幾種

(1)存儲屬性(Stored Properties)

(2)計算屬性(Computed Properties)

(3)類型屬性(Type Properties)

3.存儲屬性

1)簡單說明

存儲屬性:存儲屬性就是存儲在對象(實例)中的一個變量或者常量

存儲屬性類似於其他面向對象語言中的成員變量

1 class Person {
2     var age: Int = 1
3     var height: Double = 0.0
4     let life = 1
5 }

說明

Person類中定義了3個存儲屬性

2個變量存儲屬性:Int類型的age、Double類型的height 

1個常量存儲屬性:Int類型的life

系統並不會自動初始化上面的3個存儲屬性,需要進行手動初始化

2)存儲屬性的讀寫

  如何讀寫存儲屬性?

  直接通過點運算符(.),就可以讀寫某個對象的存儲屬性  

1 class Person {
2     var age: Int = 1
3     let life = 1
4 }
5 var p = Person()
6 p.age = 20
7 println("p的生命是\(p.life), p的年齡是\(p.age)")

說明

第5行:創建Person對象

第6行:給對象p的age屬性賦值

第7行:訪問對象p的life屬性值和age屬性值

3)延遲存儲屬性

什么是延遲存儲屬性?

延遲存儲屬性是第一次使用時才進行初始化的屬性

使用@lazy來標識一個延遲存儲屬性

1 class Person {
2     @lazy var dog: Dog = Dog()
3 }
4 var p = Person()
5 println(p.dog)

說明

  執行第5行代碼時,才會去初始化dog屬性,才真正創建了Dog對象

延遲存儲屬性的使用注意:延遲存儲屬性必須是變量,不能是常量

延遲存儲屬性的好處:讓某些資源用到時再去加載,避免一些不必要的資源浪費

 

4.計算屬性

(1)什么是計算屬性

跟存儲屬性不一樣的是,計算屬性不是直接存儲值,而是提供get和set

get:用來取值,封裝取值的過程

set:用來設值,封裝設值的過程

(2)代碼示例:

 1 class Square {
 2     // 正方形的寬度
 3       var width: Double = 0.0
 4     // 正方形的周長
 5       var girth: Double {
 6         get {
 7             // 周長 = 寬度 * 4
 8                 return width * 4
 9         }
10         set(newGirth) {
11             // 寬度 = 周長 / 4
12                    width = newGirth / 4
13         }
14     }
15 }

計算屬性舉例:

1 var s = Square()
2 s.width = 10
3 println(s.girth)
4 s.girth = 200 
5 println(s.width) 

說明

第3行代碼:調用girth屬性的get,輸出結果是40

第4行代碼:調用girth屬性的set,並且把200傳遞給newGirth參數

第5行代碼:輸出結果是50

(3)簡便的set

  set也可以不特意指定新值的參數名,新值的默認參數名叫做newValue

1 var girth: Double {
2     get {
3         return width * 4
4     }
5     set {
6         width = newValue / 4
7     }
8 }
9 s.girth = 200 

說明

  執行第9行代碼時:第6行中newValue的值就是200

(4)計算屬性的使用注意

  1)因為計算屬性的值不是固定的,因此只能用var修飾計算屬性,不能用let

 1 class Square {
 2     var girth: Double {
 3         get {
 4             return girth
 5         }
 6         set(newGirth) {
 7             girth = newGirth
 8         }
 9     }
10 }

說明:上面的代碼會引發死循環,第4行代碼會引發循環調用get,第7行代碼會引發循環調用set。

2)一個屬性不能既是存儲屬性,又是計算屬性

 1 class Square {
 2     var girth: Double = 20.0 {
 3         get {
 4             return 10.0
 5         }
 6         set() {
 7             
 8         }
 9     }
10 }

說明:上面的代碼是錯誤的

(5)只讀計算屬性

 

什么是只讀計算屬性?只提供get,沒有set的計算屬性

 

 1 class Square {
 2     var width: Double = 0.0
 3     var girth: Double {
 4         get {
 5             return width * 4
 6         }
 7     }
 8 }
 9 var s = Square()
10 s.girth = 200 

 

說明:第10行代碼會報錯

  只讀計算屬性的簡寫。只讀計算屬性可以省略get關鍵字

1 class Square {
2     var width: Double = 0.0
3     var girth: Double {
4         return width * 4
5     }
6 }
7 var s = Square()
8 s.girth = 200 

說明:第8行代碼會報錯

 

 

5.類型屬性

(1)什么是類型屬性?

 

用class關鍵字修飾的屬性,就是類型屬性,也可以稱為“類屬性”

 

class修飾的類型屬性只能是計算屬性,不能是存儲屬性

代碼示例:

1 class Circle {
2     class var PI : Double  {
3         return 3.14
4     }
5 }

說明:第2行定義的屬性PI,就是一個類型屬性

(2)類型屬性的特點

  一個類只會有一份,類的多個實例對象都共享這唯一的一份

  類型屬性的使用:類型屬性不依賴於對象而存在,因此用類名來訪問

  println(Circle.PI)

 

三、屬性監視器

1.什么是屬性監視器?

有時,需要在屬性值被修改的時候做出響應,這種情況下就可以用屬性監視器

屬性監視器,可以監視屬性值的修改過程 

  計算屬性可以直接在set中監聽屬性值的改變,而存儲屬性沒有set

可以為存儲屬性添加willSet和didSet兩個屬性監視器

(1)willSet

在設置新的屬性值之前調用

會將新的屬性值作為參數傳入,參數名默認是newValue

(2)didSet

在設置新的屬性值之后調用

會將舊的屬性值作為參數傳入,參數明默認是oldValue

2.代碼示例

 1 class Square {
 2     var width: Double = 0.0 {
 3         willSet {
 4             println("willSet---\(newValue)")
 5         }
 6         didSet {
 7             println("didSet---\(oldValue)")
 8         }
 9     }
10 }
11 var s = Square()
12 s.width = 10

打印結果:

willSet---10.0

didSet---0.0

3.使用注意

1 class Square {
2     var width: Double = 0.0 {
3         willSet { }
4         didSet { width = 20 }
5     }
6 }
7 var s = Square()
8 s.width = 10
9 println(s.width)

代碼說明

willSet和didSet在屬性初始化過程中不會被調用,只會當屬性的值在初始化之外的地方被設置時被調用

第2行代碼的初始化不會引發willSet和didSet的調用

第8行代碼的賦值會引發willSet和didSet的調用

如果在didSet監視器里為屬性賦值,這個值會替換之前設置的值

第4行對width屬性進行了再次賦值,覆蓋了第8行賦的值,因此第9行的輸出結果是20

willSet、didSet和set、get不能共存

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM