KVC簡單介紹
KVC是OC特有的,KVC本質上是在運作時,動态向對象發送setValue:ForKey:方法,為對象的屬性設定數值
是以,在使用KVC的方法之前,需要確定對象已經被正确執行個體化
- 在Swift中,如果屬性是可選的,在初始化時,不會為該屬性配置設定空間。
- 在OC中,基本資料類型就是儲存一個值,不存在可選的概念
- 是以我們需要給
設定一個初始值,否則使用KVC就會報錯。
可選的基本資料類型
如果想要在Swift中使用KVC,這個類必須要繼承自NSOject,因為KVC是OC的東西。
Swift中正确使用KVC的方式:
class Person:NSObject {
var name:String?
//給可選基本類型一個初始值
var age:Int? =
init(dict:[String:AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
}
KVC函數的調用順序:
- setValuesForKeysWithDictionary會按照字典中的key重複調用setValue:ForKey:函數
在重複調用的過程中,如果發現字典中對應的key在類中沒有對應的屬性,就會調用setValue:forUndefinedKey:函數去處理這個情況。如果沒有實作setValue:forUndefinedKey:函數時,會抛出NSUndefinedKeyException,程式崩潰。
是以應該根據具體的項目需求,來實作setValue:forUndefinedKey:函數
如果父類實作了setValue:forUndefinedKey:,子類不必再次實作這個方法了
例子:
//簡介 oc是一個面向對象即模型的開發,一般規範的開發都是以模型作為對象進行開發的。那麼在Swift中模型也同樣重要下面介紹一下模型的指派
1.介紹下 模型一鍵指派的代碼 setValuesForKeyWithDictionary 這句話的作用 是把字典Dictionary中的key對應的Value 指派給模型中的與key一樣的屬性
1)分三種情況 第一種情況是 模型中的屬性等于 字典中的額key 并且一一對應 那麼可以指派
2)第二種 模型中的屬性大于字典中的key即模型除了與字典一一對應的屬性之外還有其他屬性 那麼這個指派也有用
3)第三種 模型中的屬性小于或者字典中存在模型中沒有的屬性名字 那麼就會報錯
2.針對第三種情況 解決辦法是 在模型中加上這句話就可以了 不要進行任何操作
override func setValue(value:AnyObject?, forUndefinedKey key:String) {
} 下面附上代碼例子 //這邊是建立一個簡單 Person的模型 然後在界面指派
import UIKit
class PersonModel: NSObject {
//這是一個Person模型
/// 年齡
var age:Int =0
/// 姓名
var name:String =""
/// 性别
var sex:String =""
/// 這邊定義一個在字典裡面的key是swift中的關鍵字的屬性
var undefine:String =""
overridefunc setValue(value: AnyObject?, forUndefinedKey key:String) {
if key =="Int"
{
undefine = valueas! String
}
}
overrideinit() {
super.init()
let dic = ["age":18,"name":"Clement","sex":"man","Int":"test"]
//模型一鍵指派這個其實是運用了kvc的原理
self.setValuesForKeysWithDictionary(dic)
}
init(dic:[String:AnyObject])
{
super.init()
//模型一鍵指派這個其實是運用了kvc的原理
self.setValuesForKeysWithDictionary(dic)
}
}
import UIKit
class ViewController: UIViewController {
overridefunc viewDidLoad() {
super.viewDidLoad()
//方式1用構造函數初始化并列印結果這個是自帶的模型
let personOne =PersonModel()
print("模型的參數\(personOne.age) \(personOne.name) \(personOne.sex) \(personOne.undefine)")
//方式二用自定義的構造函數
let dic = ["age":28,"name":"Clement__","sex":"man__ ","Int":"nuewtype"]
let personTwo =PersonModel.init(dic: dic)
print("模型TWO的參數\(personTwo.age) \(personTwo.name) \(personTwo.sex) \(personTwo.undefine)")
//方式三不寫構造函數(即不用init)
let personThree =PersonModel()
let dicThree = ["age":38,"name":"Clement__three","sex":"man__Three","Int":"nuewtype_three"]
//外部對模型進行指派
personThree.setValuesForKeysWithDictionary(dicThree)
print("模型Three的參數\(personThree.age) \(personThree.name) \(personThree.sex) \(personThree.undefine)")
}
overridefunc didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//輸出結果
模型的參數18 Clement man test
模型TWO的參數28 Clement__ man__ nuewtype
模型Three的參數38 Clement__three man__Three nuewtype_three