iOS|swift之kvc

===========kvc KVC是OC特有的,KVC本质上是在运行时,动态向对象发送setValue:ForKey:方法,为对象的属性设置数值
因此,在使用KVC的方法之前,需要确保对象已经被正确实例化
在Swift中,如果属性是可选的,在初始化时,不会为该属性分配空间。
在OC中,基本数据类型就是保存一个值,不存在可选的概念
所以我们需要给可选的基本数据类型设置一个初始值,否则使用KVC就会报错。
如果想要在Swift中使用KVC,这个类必须要继承自NSOject,因为KVC是OC的东西。



KVC函数的调用顺序:
setValuesForKeysWithDictionary会按照字典中的key重复调用setValue:ForKey:函数
在重复调用的过程中,如果发现字典中对应的key在类中没有对应的属性,就会调用setValue:forUndefinedKey:函数去处理这个情况。如果没有实现setValue:forUndefinedKey:函数时,会抛出NSUndefinedKeyException,程序崩溃。
所以应该根据具体的项目需求,来实现setValue:forUndefinedKey:函数
如果父类实现了setValue:forUndefinedKey:,子类不必再次实现这个方法了。


在 Swift 中想要兼容 KVC,需要该类继承 NSObject。下面是 KVC 中常用的几个方法:


根据传入的 key,设置 value:
func setValue(_ value:Any?, forKey key:String)


根据传入的 keyPath,设置 value,keyPath 即键路径可利用 . 遍历至键:
func setValue(_ value:Any?, forKeyPath keyPath:String)


根据传入的字典,设值,如果字典中有对象不存在的属性,则会抛出异常:
func setValuesForKeys(_ keyedValues: [String :Any])


当为不存在的某个键设值时,默认调用该方法抛出 NSUndefinedKeyException 异常,子类可重写该方法:
func setValue(_ value:Any?, forUndefinedKey key:String)


设置特定键的值为 nil 时,默认调用该方法抛出 NSInvalidArgumentException,子类可重写该方法(注:官方称该方法针对标量值(scalar value),例如整型和浮点型)对于其他类型没有提到,在 Demo 中有详细的列出是否支持):
func setNilValueForKey(_ key:String)


返回传入指定键的对应值:
func value(forKey key:String) -> Any?


返回传入指定键路径的对应值:
func value(forKeyPath keyPath:String) -> Any?


返回传入未定义的键路径的对应值:
func value(forUndefinedKey key:String) -> Any?


=====================kvc字典转模型===============================================

*****第一层模型
import UIKit


class LYBHomeLunboModel:NSObject {
@objc var name:String?="11" //swift4.0中要加上@objc,否则在外面调用不到

@objc var age:NSNumber?
@objc var phones:[LYBPhonesModel]?
init(dict:[String:Any]) {
super.init()
setValuesForKeys(dict)
}
override func setValue(_ value:Any?, forKey key:String) {

if key=="phones"{
let temp = valueas! [AnyObject]
var resultArray = [LYBPhonesModel]()
for dictin temp {
resultArray.append(LYBPhonesModel(dict: dictas! [String :AnyObject]))

}
phones = resultArray
return
}
super.setValue(value, forKey: key)
}
override func setValue(_ value:Any?, forUndefinedKey key:String) {
}


}
*****************第二层模型*********

import UIKit


class LYBPhonesModel:NSObject {
@objc var name:String?
@objc var number:String?

init(dict: [String:AnyObject]) {
super.init()

setValuesForKeys(dict)
}

override func setValue(_ value:Any?, forKey key:String) {
super.setValue(value, forKey: key)
}
override func setValue(_ value:Any?, forUndefinedKey key:String) {

}
}





*****************
//kvc
func swiftkvc(){


//1.这是一个JSON字符串
let jsonStr ="[{\"name\": \"hangge\", \"age\": 100, \"phones\": [{\"name\": \"公司\",\"number\": \"123456\"}, {\"name\": \"家庭\",\"number\": \"001\"}]}, {\"name\": \"big boss\",\"age\": 1,\"phones\": [{ \"name\": \"公司\",\"number\": \"111111\"}]}]"

//2.吧JSON字符串变成data数据
if let jsonData = https://www.it610.com/article/jsonStr.data(using:String.Encoding.utf8, allowLossyConversion:false) {

//***************系统的序列化成json*************
do{
////3.吧jsondata转换成JSON对象(即字典,或字典数组)
iflet dictArr:[[String:Any]]=(tryJSONSerialization.jsonObject(with:jsonData , options: .allowFragments)as?[[String :Any]]){
let dict:[String:Any]=dictArr[1]
let model:LYBHomeLunboModel=LYBHomeLunboModel(dict:dict)

print("\(model.phones![0].name!)")
}
}
catch {


}


}

================== 【iOS|swift之kvc】

    推荐阅读