標籤:image elf ret logs 釋放 完全 link 執行個體化 name
- 建構函式
- 非 Optional 屬性, 都必須在建構函式中設定初始值, 從而保證對象在執行個體化的時候, 屬性都能被正確的初始化
- 建構函式的目的: 給自己的屬性分配空間並且設定初始值
- 在調用父類的建構函式之前, 必須保證本類的屬性都已經完成初始化
- 調用父類的建構函式, 給父類的屬性分配空間並且設定初始值
- 如果重載了建構函式, 並且沒有重寫父類的 init 方法,系統不再提供 init 建構函式(預設是會有的), 因為預設的建構函式, 不能給本類的屬性分配空間
// Person 類沒有 ‘初始化器‘s, 建構函式可以有多個, 預設是 initclass Person: NSObject{ var name: String // 重寫: 父類有這個方法, 子類重新實現, 需要 override 關鍵字 override init() { // 給 self.name 初始化: 分配空間, 設定初始值 name = "AAA" super.init() } // 重載: 函數名相同, 會是參數和個數不同 // 重載可以給自己的屬性從外部設定初始值 init(name: String) { // 使用參數的 name 設定屬性 self.name = name // 調用父類型的建構函式 super.init() }}
- KVC 建構函式
- 在設定模型的時候, 如果是對象, 通常是可選的, 在需要的時候建立, 避免寫建構函式, 可以最佳化代碼
- 如果是基礎資料型別 (Elementary Data Type), 不能設定成可選的, 而且要設定初始值, 否則 KVC 會崩潰
- 如果需要使用 KVC 設定屬性值, 屬性不能是 private 的
- 在使用 KVC 方法之前, 應該調用 super.init 方法, 保證對象被完全初始化
- 如果子類沒有重寫父類的方法, 調用的時候, 會直接調用父類的方法
class Person: NSObject{ // name 屬性是可選的, 在 OC 中很多的屬性都是在需要的時候建立的 // 例如 vc.view / tableViewCell.textLabel / detailLabel / imageView //消極式載入:在需要的時候再建立 var name: String? // 給基礎資料型別 (Elementary Data Type)初始化 // var age: Int? 當使用 KVC 會提示無法找到 age 的 KEY //原因: Int是一個基礎資料型別 (Elementary Data Type)的結構體, OC中只有基礎資料型別 (Elementary Data Type) var age: Int = 0 // 如果是 private 屬性, 使用 KVC 設定值的時候, 同樣無法設定 // 如果設定成 private 屬性 / 方法, 禁止外部存取的 // private var title: String? init(dict: [String : Any]) { // 保證對象已經完全初始化完成 super.init() // 使用 self 的方法 setValuesForKeys 之前, 應該調用 super.init() // KVC的方法,是OC的方法,在運行時給對象發生訊息,要求對象已經執行個體化完成 setValuesForKeys(dict) // super.init() } // 重寫父類的方法 override func setValue(_ value: Any?, forUndefinedKey key: String) { // 設定 調用 super, 將父類的代碼實現完全覆蓋, 防止索引值對不匹配時的崩潰 }}
- 便利建構函式
- 便利建構函式允許返回 nil, 正常的建構函式一定會建立對象
- 便利建構函式的目的: 判斷給定的參數是否符合條件, 如果不符合條件, 返回 nil, 不會建立對象, 減少記憶體的開銷
- 只有便利建構函式中使用 self.init 來構造當前對象; 沒有 convenience 關鍵字的建構函式是負責建立對象的, 反之是用來檢查條件的, 本身不負責對象的建立
- 如果要在便利建構函式中使用當前對象的屬性, 一定要在 self.init 之後
- 便利建構函式不能被重寫, 或者調用 super
class Student: NSObject{ var name: String? var age: Int = 0 // 便利建構函式 convenience init?(name: String, age: Int) { if age > 100 { return nil } // 使用 self 訪問 name 之前, 應該調用 self.init // self.name = name // 執行個體化當前對象 self.init() // 執行到此 self 才允許被訪問, 才能訪問對象的屬性 self.name = name }}
- 解構函式
- 跟蹤對象的銷毀
- 沒有 func 不讓外面調用
- 沒有 () 不讓重載
- 在對象被銷毀前調用
- 類似於 OC 的 dealloc
deinit { /* 1.跟蹤對象的銷毀 2.必須釋放 -通知, 不釋放不會崩潰, 但是會造成記憶體泄露 - KVO,不釋放會崩潰 - NSTimer / CADisplayLink */ }
Swift學習筆記九:類 Class