KVC原理
描述
Key-value coding is a mechanism enabled by the NSKeyValueCoding
informal protocol that objects adopt to provide indirect access to their properties.
kvc 是由NSKeyValueCoding非正式协议采用的一种机制,对象通过该协议来提供属性的间接访问
![](https://img.haomeiwen.com/i5225391/848c2f6b72ad6b4f.png)
![](https://img.haomeiwen.com/i5225391/90ec2ef70bdbb4a1.png)
执行结果为
IFLArchitecture[15333:450053] -[IFLKVCObject setName:] -- name: kvc_name1
根据测试,发现 setValue forKey, 会先判断是否含有setName, 有的话执行 setName
否则,判断有无 _setName ,有的话执行 _setName
如果 key不存在的话,
执行 - (void)setValue:(id)value forUndefinedKey:(NSString *)key
accessInstanceVariablesDirectly
![](https://img.haomeiwen.com/i5225391/5f5eb52728992b44.png)
![](https://img.haomeiwen.com/i5225391/8cec6104d143d1da.png)
![](https://img.haomeiwen.com/i5225391/e07e178355980e96.png)
如果 accessInstanceVariablesDirectly 返回YES
则 setValue forKey 根据 _<key> _is<Key> <key> is<Key> 的顺序查找变量进行设置
如果 accessInstanceVariablesDirectly 返回NO
则 setValue forKey 将执行 setValue: forUndefinedKey:
现在把set的方法全都注释掉,看下成员变量 name们的值
![](https://img.haomeiwen.com/i5225391/022602957573ea9d.png)
![](https://img.haomeiwen.com/i5225391/e0575b0e2a8f7627.png)
![](https://img.haomeiwen.com/i5225391/51c2ac875b782907.png)
![](https://img.haomeiwen.com/i5225391/68f03dbbb170d114.png)
发现就 _name有值
注释掉 _name 继续测试
![](https://img.haomeiwen.com/i5225391/cc44ff791e3bf9b4.png)
![](https://img.haomeiwen.com/i5225391/0f225ee9a9be6556.png)
此时 _isName 有值
注释掉 _isName 继续测试
![](https://img.haomeiwen.com/i5225391/cea1f20e23f49a17.png)
![](https://img.haomeiwen.com/i5225391/60d27455122ac2d4.png)
此时 name 有值
注释掉 name 继续测试
![](https://img.haomeiwen.com/i5225391/d9d3fd752ae4cb05.png)
![](https://img.haomeiwen.com/i5225391/3b341ab5651d8bfc.png)
此时 isName有值
set方法的执行顺序
![](https://img.haomeiwen.com/i5225391/55e5ebfe73db3c64.png)
如果我们通过注释测试,发现
set执行顺序为 set<Key> _set<Key> setIs<Key>
value设置的顺序为 _<key> _is<Key> <key> is<Key>
get方法执行顺序
![](https://img.haomeiwen.com/i5225391/b33e66ffba0d9a60.png)
![](https://img.haomeiwen.com/i5225391/5e9c00b5ed783f62.png)
![](https://img.haomeiwen.com/i5225391/b59f5d60e69aedb0.png)
注释掉 set get
![](https://img.haomeiwen.com/i5225391/b04966a766e67efc.png)
![](https://img.haomeiwen.com/i5225391/904a07dc157ebc9e.png)
取值结果为null
因为取值顺序为 _<key> _is<Key> <key> is<Key>
自定义KVC流程
自定义实现说白了就是对前面 key的拼接 大小写处理 判断方法实现
自定义setValue forKey
![](https://img.haomeiwen.com/i5225391/2e28ab8607084f44.png)
-
顺序判断set<Key> _set<Key> setIs<Key> 是否实现
-
判断 accessInstanceVariablesDirectly 是否允许直接访问实例变量
-
顺序查找 _<key> _is<Key> <key> is<Key> 实例变量
-
object_setIvar 实例变量赋值
![](https://img.haomeiwen.com/i5225391/6660df978e10a4a9.png)
自定义 getValueForKey 与 set大同小异
![](https://img.haomeiwen.com/i5225391/ff114626b1af5851.png)