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】
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 太平之莲
- 闲杂“细雨”
- 七年之痒之后
- 深入理解Go之generate
- 由浅入深理解AOP
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 生活随笔|好天气下的意外之喜
- 感恩之旅第75天
- 2020-04-07vue中Axios的封装和API接口的管理