swift /// `重寫`構(gòu)造函數(shù) /// /// - parameter dict: 字典 /// /// - returns: Person 對象 init(dict: [String: AnyObject]) { setValuesForKeysWithDictionary(dict) }
以上代碼編譯就會報錯!
原因:
KVC 是 OC 特有的,KVC 本質(zhì)上是在運行時,動態(tài)向?qū)ο蟀l(fā)送 setValue:ForKey: 方法,為對象的屬性設(shè)置數(shù)值
因此,在使用 KVC 方法之前,需要確保對象已經(jīng)被正確實例化
添加 super.init() 同樣會報錯
原因:
必選屬性必須在調(diào)用父類構(gòu)造函數(shù)之前完成初始化分配工作
講必選參數(shù)修改為可選參數(shù),調(diào)整后的代碼如下:
```swift /// 個人模型 class Person: NSObject {
/// 姓名
var name: String?
/// 年齡
var age: Int?
/// `重寫`構(gòu)造函數(shù)
///
/// - parameter dict: 字典
///
/// - returns: Person 對象
init(dict: [String: AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
} ```
運行測試,仍然會報錯
錯誤信息:this class is not key value coding-compliant for the key age. -> 這個類的鍵值 age 與 鍵值編碼不兼容
原因:
在 Swift 中,如果屬性是可選的,在初始化時,不會為該屬性分配空間
而 OC 中基本數(shù)據(jù)類型就是保存一個數(shù)值,不存在可選的概念
解決辦法:給基本數(shù)據(jù)類型設(shè)置初始值
修改后的代碼如下:
```swift /// 姓名 var name: String? /// 年齡 var age: Int? = 0
/// 重寫構(gòu)造函數(shù) /// /// - parameter dict: 字典 /// /// - returns: Person 對象 init(dict: [String: AnyObject]) { super.init()
setValuesForKeysWithDictionary(dict)
} ```
提示:在定義類時,基本數(shù)據(jù)類型屬性一定要設(shè)置初始值,否則無法正常使用 KVC 設(shè)置數(shù)值
KVC 函數(shù)調(diào)用順序
```swift init(dict: [String: AnyObject]) { super.init()
setValuesForKeysWithDictionary(dict)
}
override func setValue(value: AnyObject?, forKey key: String) { print("Key (key) (value)")
super.setValue(value, forKey: key)
}
// NSObject 默認在發(fā)現(xiàn)沒有定義的鍵值時,會拋出 NSUndefinedKeyException 異常 override func setValue(value: AnyObject?, forUndefinedKey key: String) { print("UndefinedKey (key) (value)") } ```
setValuesForKeysWithDictionary 會按照字典中的 key 重復(fù)調(diào)用 setValue:forKey 函數(shù)
如果沒有實現(xiàn) forUndefinedKey 函數(shù),程序會直接崩潰
NSObject 默認在發(fā)現(xiàn)沒有定義的鍵值時,會拋出 NSUndefinedKeyException 異常
如果實現(xiàn)了 forUndefinedKey,會保證 setValuesForKeysWithDictionary 繼續(xù)遍歷后續(xù)的 key
如果父類實現(xiàn)了 forUndefinedKey,子類可以不必再實現(xiàn)此函數(shù)
子類的 KVC 函數(shù)
```swift /// 學(xué)生類 class Student: Person {
/// 學(xué)號
var no: String?
} ```
如果父類中已經(jīng)實現(xiàn)了父類的相關(guān)方法,子類中不用再實現(xiàn)相關(guān)方法