iOS开发 KVC方法解析
kvc
kvc 和 kvo经常放在嘴边,开发中也会经常用到,或者被封装在第三方的库中。比如常用的mjextension、模型字典互转工具等。今天简单写一下 kvc(key-value-coding)。
引用一下概念:
key-value-coding, 即键值编码. 它是一种不通过存取方法, 而是通过属性名称字符串间接访问属性的机制.是指在 ios 开发中,允许开发者通过 字符串键和键路径直接访问或赋值对象属性.
vc方法">kvc方法
先来定义两个类,雇员类ky_employee,和车辆类ky_car,在后面的代码使用。如下:
@objc class ky_employee: nsobject { /// 姓名 @objc var name: string = "" /// 年龄 @objc var age: string = "" /// 家乡 @objc var hometown: string = "" /// 生日 @objc var birthday: string = "" /// 书籍 @objc var books: [string] = [] /// 车辆 @objc var car: ky_car } @objc class ky_car: nsobject { /// 车牌号 @objc var platenum: string = "" /// 车辆颜色 @objc var color: uicolor }
1、set
(1)setvalue
// swift open func setvalue(_ value: any, forkey key: string) open func setvalue(_ value: any, forkeypath keypath: string) // oc - (void)setvalue:(nullable id)value forkey:(nsstring *)key; - (void)setvalue:(nullable id)value forkeypath:(nsstring *)keypath;
普通的属性赋值使用前者即可:
var emp = ky_employee() emp.setvalue("小明", forkey: "name")
但,对car中的属性赋值时,需要使用后者的赋值方法,该方法在链式赋值时使用。例如我们定义的雇员类中,其属性car是另一个自定义的类,则,需要使用setvalue: forkeypath::
// kvc链式赋值 var emp = ky_employee() var car = ky_car() emp.car = car emp.setvalue("京a8888", forkeypath: "car.platenum")
(入门级提示)使用路径赋值时,需要将属性类初始化,如:emp.car = ky_car()。
(2)字典转模型
字典转模型,需要字典中的key和类属性相对应,如果字典中的key值在模型类中未找到,会抛出异常。
// 定义一个字典,准备赋值给 ky_employee var dict: [string: any] = ["name": "康鹏鹏", "age": "25", "hometown": "河北邯郸魏县", "birthday": "1993-01-28", "car": ["platenum": "京a1111", "color": uicolor.white], "books": ["钢铁是怎样炼成的", "ios高级开发指南", "乔布斯传"]]; // 使用字典给模型赋值 var emp = ky_employee() emp.setvaluesforkeys(dict)
(3)set异常
上面两个说的都是key可以在class模型中找到对应的属性。当key值无法在模型中找到对应的属性时,会调用下面这个方法:
open func setvalue(_ value: any, forundefinedkey key: string)
为了保证程序不崩溃,需要在模型类中重写该方法做异常处理!
在oc中:setter方法没找到对应的key属性, 那么按 _key, _iskey, key, iskey 的顺序搜索成员名。 在swift中:因为swift语法没有成员变量,所以不会如上oc中搜索。(4)setnil
有博客说:给属性赋值nil会调用方法 func setnilvalueforkey(_ key: string) 。根据我的实测:
// 给属性赋值nil var emp = ky_employee() emp.setvalue(nil, forkey: "name")
而func setnilvalueforkey(_ key: string)并没有被调用。
若使用setnilsetnilvalueforkey方法,需要重写该方法,否则默认会抛出异常。
2、get
(1)getvalue
kvc读取属性值常用的方法也就下面几个:
// 直接读取属性值 open func value(forkey key: string) -> any // 根据链式路径读取属性值,如读取emp.car中的属性 open func value(forkeypath keypath: string) -> any // 获取数组类型属性的值, open func mutablearrayvalue(forkey key: string) -> nsmutablearray // 根据路径获取数组类型属性的值,如获取emp.car中一个数组类型属性的值 open func mutablearrayvalue(forkeypath keypath: string) -> nsmutablearray // 根据传入的key数组,返回key-value字典 open func dictionarywithvalues(forkeys keys: [string]) -> [string : any]
找不到与key对应的属性时,会调用value(forundefinedkey key: string) -> any,该方法默认抛出异常。可以重写该方法做容错处理。
3、字典转模型框架实现(dict to model)
字典和模型的相互转换,需要配合runtime使用。日后抽时间再写。
上一篇: 《构建之法》阅读-第一次作业
推荐阅读
-
详解iOS App开发中UIViewController的loadView方法使用
-
深入解析iOS应用开发中九宫格视图布局的相关计算方法
-
iOS应用开发中对UIImage进行截取和缩放的方法详解
-
详解iOS开发中UITableview cell 顶部空白的多种设置方法
-
iOS应用开发中矢量图的使用及修改矢量图颜色的方法
-
iOS应用开发中使UITextField实现placeholder属性的方法
-
iOS程序开发中设置UITableView的全屏分隔线的方法(不画线)
-
解析Android开发中多点触摸的实现方法
-
举例讲解iOS应用开发中hitTest触摸事件的编写方法
-
iOS开发教程之APP内部切换语言的实现方法