KVC原理探秘

2020-02-24  本文已影响0人  天津的树懒

KVC的全称是"Key-Value Coding",俗称“键值编码”,可以通过一个key来访问对象的某个属性。

KVC的一般应用

对于KVC相信大家并不陌生,我们一般常用KVC的下面两个方法来设置对象的属性值或者成员变量的值:

"- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;"
"- (void)setValue:(id)value forKey:(NSString *)key;"

一般使用下面的两个方法来获取对象的属性值或者成员变量的值:

"(id)valueForKeyPath:(NSString *)keyPath;"
"(id)valueForKey:(NSString *)key;"

除此之外,使用KVC方式来修改对象的属性值的时候也会触发KVO的监听方法。

Github Demo

以上是对KVC的几种常用的应用场景做的一个讲解。下面将重点剖析使用KVC的API来设置或者获取对象的属性值或成员变量值的原理。

KVC设置对象的属性值或者成员变量值的原理:

创建一个ZPPerson类,在ZPPerson.h文件中撰写它的成员变量:

成员变量

在ZPPerson.m文件中撰写:

image.png

然后修改person对象的age属性的值:

[self.person setValue:[NSNumber numberWithInt:10] forKey:@"age"];

当调用KVC的"setValue: forKey: "方法以后,系统首先会在对象类的.m文件中寻找"setKey:"实例方法的实现,如果找到的话就传递参数、调用方法,如果找不到的话再在这个.m文件中继续寻找"_setKey:"实例方法的实现,如果找到的话就传递参数、调用方法。通过上述的两个实例方法来修改对象的属性值。如果上述的两个实例方法都找不到的话就接着再在这个.m文件中继续寻找"accessInstanceVariablesDirectly"类方法,如果找到的话就查看这个方法的返回值,如果返回值为NO,则意味着不能直接访问这个对象类的成员变量,程序会崩溃,在控制台中会抛出异常"NSUnknownKeyException"。如果返回值为YES,则意味着可以直接访问这个对象类的成员变量,并且会按照_key、_isKey、key、isKey的顺序来查找成员变量,如果找到的话则给它直接赋值,通过这种方式来修改对象类中的成员变量,如果还是没有找到的话则程序会崩溃,并且在控制台中会抛出异常"NSUnknownKeyException"。

以上就是通过KVC的方式修改对象的属性值或者成员变量值的原理。

还可以从下图中直观地看出运行原理:

利用KVC的方法设置对象的属性值或者成员变量值的原理图

Github Demo

KVC获取对象的属性值或者成员变量值的原理:

创建一个ZPPerson类,在ZPPerson.h文件中撰写它的成员变量:

成员变量

在ZPPerson.m文件中撰写:

image.png

然后获取person对象的age属性的值:

NSLog(@"%@", [person valueForKey:@"age"]);

当调用KVC的"valueForKey:"方法以后,系统会先在对象类的.m文件中按照getKey、key、isKey、_key的顺序查找这些实例方法,如果找到的话就返回这些方法里面的返回值,从而达到了通过KVC的方式获取对象的属性值的目的。如果上述的那些实例方法都没有找到的话就接着再在这个.m文件中寻找"accessInstanceVariablesDirectly"类方法,如果找到的话就查看这个方法的返回值,如果返回值为NO,则意味着不能访问这个对象类的成员变量,程序会崩溃,在控制台中会抛出异常"NSUnknownKeyException"。如果返回值为YES,则意味着可以直接访问这个对象类里面的成员变量,并且会按照_key、_isKey、key、isKey的顺序来查找成员变量,如果找到的话则获取它的值,如果还是没有找到的话则程序会崩溃,并且在控制台中会抛出异常"NSUnknownKeyException"。

以上就是通过KVC的方式获取对象的属性值或者成员变量值的原理。

还可以从下图中直观地看出运行原理:

利用KVC的方法获取对象的属性值或者成员变量值的原理图

Github Demo

”三人行,必有我师焉“, 欢迎各位批评指正。
如果您还觉得我写的不错的话请您点赞加关注,您的肯定是我前进的最大动力!
我是爱学习也爱您的树懒O(∩_∩)O

上一篇下一篇

猜你喜欢

热点阅读