kvc是如何实现的

  原文 : https://www.cnblogs.com/zy1987/p/4616063.html 

更详细的文章作为参考补充:  http://www.cocoachina.com/ios/20180305/22441.html

KVC和KVO都属于键值编程,KVO底层实现机制是isa-swizzing,里面也用到了键值编码,所以本来想放在一起讲的。但是篇幅有限所以就分成了两篇博文 KVO实现机制传送门

KVC概述

  • KVC是Key Value Coding的简称。它是一种可以通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。
  • 关键方法定义在 NSKeyValueCodingProtocol
  • KVC支持类对象和内建基本数据类型。

KVC使用

  • 获取值
    valueForKey: 传入NSString属性的名字。
    valueForKeyPath: 属性的路径,xx.xx
    valueForUndefinedKey 默认实现是抛出异常,可重写这个函数做错误处理

  • 修改值
    setValue:forKey:  一级属性,label.text
    setValue:forKeyPath: 多级属性。比如cell.label.text
    setValue:forUnderfinedKey:
    setNilValueForKey: 对非类对象属性设置nil时调用,默认抛出异常。

KVC键值查找

搜索单值成员

  • setValue:forKey:搜索方式

1、首先搜索setKey: 和 setIsKey: 。(key指成员变量名,首字母大写)

2、上面的setter方法没找到,如果类方法accessInstanceVariablesDirectly返回YES(默认YES)。那么按 _key,_isKey,key,iskey的顺序搜索成员名。返回NO,跳过寻找变量的过程(NSKeyValueCodingCatogery中实现的类方法)

3、如果没有找到成员变量,调用setValue:forUnderfinedKey:

比如说如下的一行KVC代码:

[site setValue:@"sitename" forKey:@"name"];

//会被编译器处理成

SEL sel = sel_get_uid(setValue:forKey);
IMP method = objc_msg_loopup(site->isa,sel);
method(site,sel,@"sitename",@"name");
  • valueForKey:的搜索方式

1、首先按getKey,key,isKey的顺序查找getter方法,找到直接调用。如果是BOOL、int等内建值类型,会做NSNumber的转换。

2、上面的getter没找到,查找countOfKey、objectInKeyAtindex、KeyAtindexes格式的方法。如果countOfKey和另外两个方法中的一个找到,那么就会返回一个可以响应NSArray所有方法的代理集合的NSArray消息方法。

3、还没找到,查找countOfKey、enumeratorOfKey、memberOfKey格式的方法。如果这三个方法都找到,那么就返回一个可以响应NSSet所有方法的代理集合。
4、还是没找到,如果类方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey,key,iskey的顺序搜索成员名。返回NO,直接到5,no可以保护自己类的私有变量。

5、再没找到,调用valueForUndefinedKey。

说下accessInstanceVariablesDirectly

官方描述:
+ (BOOL)accessInstanceVariablesDirectly
Description
Returns a Boolean value that indicates whether the key-value coding methods should access the corresponding instance variable directly on finding no accessor method for a property.
大意是,在没有找到存取器的时候才调用该方法。返回一个布尔值,该值指示键值编码方法在找不到属性的访问器方法时是否应直接访问相应的实例变量。

 

最后补充一个对数组的操作https://blog.csdn.net/eagle199012/article/details/45740239:
@min : 最小值
@max : 最大值
@avg : 平均值
@sum : 总和

    NSArray *numberArray = @[@2,@1,@6];
    // 最大值
    NSNumber * max = [numberArray valueForKeyPath:@"@max.intValue"] ;
    // 最小值
    NSNumber * min = [numberArray valueForKeyPath:@"@min.intValue"] ;
    // 平均值
    NSNumber * avg = [numberArray valueForKeyPath:@"@avg.intValue"] ;
    // 总和
    NSNumber * sum = [numberArray valueForKeyPath:@"@sum.intValue"] ;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值