KVC和KVO底层原理
【KVC和KVO底层原理】了解更多iOS底层原理知识,关注腾讯课堂八点钟学院iOS高级开发
iOS学习交流QQ群431449751
KVC和KVO想必都熟知的一个名词,采用观察者模式,那么KVC到底是个什么,KVO又是什么,它们之间是怎样关联的,一起来解决这些疑惑。
像我们银行卡bankCard的余额变动,会及时通知给用户,这种场景就运用了观察者模式,达到了系统的高效高性能处理;当你了解KVC机制,会恍然大悟,只要知道一个UI的结构,就能对他做任意的修改,所以了解KVC和KVO的机制原理还是很重要的。
一、首先先讲KVC,KVC简称KeyValueCoding,是一个基于NSKeyValueCoding非正式协议的机制,就是直接通过key值对对象的属性进行存取操作,而不是通过明确的存取方法,简而言之也就是一系列规则和方法进行的存取操作,那接下来深入了解KVC在底层做了些什么。
注:NSObject是定义了KVC的,所以继承NSObject的对象都支持KVC,基本上所有的OC对象都支持KVC。1、 首先我们了解取值功能,MyObject对象代码如下:
@interface MyObject : NSObject
@property (nonatomic, strong)NSString *name;
@end
我们对该对象的name进行取值
myObject = [[MyObject alloc] init];
myObject.name = @"八点钟";
NSLog(@"%@", myObject.name);
当执行myObject.name时,系统自动会执行- (NSString*)name方法,这个方法在property建立的时候,系统会默认生成,也会对应的生成setName方法。
2、我们换以一种形式来访问,在没有主动建立property的情况下,MyObject对象代码如下:
@interface MyObject : NSObject
@end
我们对该对象的name进行取值
myObject = [[MyObject alloc] init];
NSLog(@"%@",[myObject valueForKey:@"name”]);
当执行[myObject valueForKey:@”name”]时,我们没有定义属性name,系统就会根据key来进行一个搜索,那么KVC执行规则是:依次搜索-(NSString*)getName方法,- (NSString*)name方法,- (NSString*)isName方法,这三个方法的先后顺序来查找,如果有,则执行相应的方法,(这是按NSString类型的查找规则)。
如果没有则继续找,因为key:@”name”,系统也不知道查找的name是什么类型的,那么系统会按照其他数据类型的方式继续找,如数组NSArray查找方式是会找这两个方法
-(NSUInteger)countOfName
-(id)objectInNameAtIndex:(NSUInteger)index
如果找到了就执行。
依此类推还有其他数据类型的查找方式,不一一例举出来了,重点是了解有这么一个过程,KVC原理。
如果按照KVC规则没有查找到相应的方法则会调用valueForUndefinedKey:方法,系统直接抛出异常,程序Crash, 我们可以重写valueForUndefinedKey这个方法,则不会导致系统抛出异常,防止程序奔溃。
那么KVC还提供了valueForKeyPath:等这些取值方法。
注意如果是BOOL或者int等值类型,会做NSNumber转换。
讲了这么多,来一波代码,看现象:(依次注释MyObject类里面的方法来看效果就一目了然,代码简单,磨起键盘吧,高手是敲出来的,背后都有一部撸的辛酸史,实践出真知,代码撸起来)
文章图片
文章图片
二、接下来我们来研究存的操作(修改对象属性)
property的上面已经提到了,来看另一种方式
setValue:forKey或setValue:forKeyPath等方法。
对象代码:(MyObjectTwo类没有定义任何属性)
@interface MyObjectTwo :NSObject
@end
执行代码
myObjectTwo = [[MyObjectTwoalloc]init];
[myObjectTwo setValue:@"八点种学院" forKey:@"name"];
调用setValue:forkey:代码时,系统没有自定属性name,那么底层会怎么做呢, 系统执行的操作:
系统会去找setName:属性值方法,如果没有找到setName:方法,KVC机制会检查(BOOL)accessInstanceVariablesDirectly方法有没有返回YES,系统默认是返回YES的,但我们可以重写该方法,返回NO,如果是返回NO,没找到setName方法,那么系统就会执行setValue:ForUndefineKey:方法,系统抛出异常,程序Crash。返回YES,继续搜索类里面成员变量,搜索顺序依次是_name、_isName、name、isName,如果找了相应变量,就停止寻找,对该变量进行修改。
动起手来,看机制,一切尽在撸
文章图片
文章图片
注意:当对NSDictionary对象使用KVC时,valueForKey:和objectForKey:效果一样。
可以看出利用KVC可以修改类的私有变量,可以修改IOS隐藏一些属性,如UITextField的placeHolderText默认style在需求中达不到要求,我们可以直接通过KVC快速定义自己的style,代码如下:
[textField setValue:[UIColor redColor] forKeyPath:@"placeholderLabel.textColor"];
如果你了解一个UI的内部结构,你可以通过KVC可以改变系统默认的任何效果,KVC是不是很强大。
本文简单的讲述了KVC的内部原理,如果一个框架没有KVC机制的时候,我们就可以简单实现自己的KVC,一个程序猿追求的应该不是对工具的使用,而是理解原理机制,创造工具,那么你就是牛B的。编程的目的是希望写出高效率高性能的东西,而机制对任何一种语言都实用,所以常说语言是相通的,你精通一门就精通大部分语言了。
更多复杂KVC使用方式期待后续;
夜深,下篇再继续结合KVC来讲解KVO
了解更多IOS底层原理知识请关注腾讯课堂八点钟学院IOS高级开发
https://ke.qq.com/course/171725
IOS学习交流QQ群:431449751
推荐阅读
- 急于表达——往往欲速则不达
- 第三节|第三节 快乐和幸福(12)
- 20170612时间和注意力开销记录
- 2.6|2.6 Photoshop操作步骤的撤消和重做 [Ps教程]
- 对称加密和非对称加密的区别
- 眼光要放高远
- 樱花雨
- 前任
- 2020-04-07vue中Axios的封装和API接口的管理
- 烦恼和幸福