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; @end123123我们对该对象的name进行取值myObject = [[MyObject alloc] init];myObject.name = @"八点钟";NSLog(@"%@", myObject.name);123123当执行myObject.name时,系统自动会执行- (NSString*)name方法,这个方法在property建立的时候,系统会默认生成,也会对应的生成setName方法。2、我们换以一种形式来访问,在没有主动建立property的情况下,MyObject对象代码如下:@interface MyObject : NSObject@end1212我们对该对象的name进行取值myObject = [[MyObject alloc] init];NSLog(@"%@",[myObject valueForKey:@"name”]);1212当执行[myObject valueForKey:@”name”]时,我们没有定义属性name,系统就会根据key来进行一个搜索,那么KVC执行规则是:依次搜索-(NSString*)getName方法,- (NSString*)name方法,- (NSString*)isName方法,这三个方法的先后顺序来查找,如果有,则执行相应的方法,(这是按NSString类型的查找规则)。如果没有则继续找,因为key:@”name”,系统也不知道查找的name是什么类型的,那么系统会按照其他数据类型的方式继续找,如数组NSArray查找方式是会找这两个方法-(NSUInteger)countOfName-(id)objectInNameAtIndex:(NSUInteger)index1212如果找到了就执行。依此类推还有其他数据类型的查找方式,不一一例举出来了,重点是了解有这么一个过程,KVC原理。如果按照KVC规则没有查找到相应的方法则会调用valueForUndefinedKey:方法,系统直接抛出异常,程序Crash, 我们可以重写valueForUndefinedKey这个方法,则不会导致系统抛出异常,防止程序奔溃。那么KVC还提供了valueForKeyPath:等这些取值方法。注意如果是BOOL或者int等值类型,会做NSNumber转换。讲了这么多,来一波代码,看现象:(依次注释MyObject类里面的方法来看效果就一目了然,代码简单,磨起键盘吧,高手是敲出来的,背后都有一部撸的辛酸史,实践出真知,代码撸起来)二、接下来我们来研究存的操作(修改对象属性)property的上面已经提到了,来看另一种方式setValue:forKey或setValue:forKeyPath等方法。对象代码:(MyObjectTwo类没有定义任何属性)@interface MyObjectTwo :NSObject@end1212执行代码myObjectTwo = [[MyObjectTwoalloc]init];[myObjectTwo setValue:@"八点种学院" forKey:@"name"];1212调用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"];11如果你了解一个UI的内部结构,你可以通过KVC可以改变系统默认的任何效果,KVC是不是很强大。本文简单的讲述了KVC的内部原理,如果一个框架没有KVC机制的时候,我们就可以简单实现自己的KVC,一个程序猿追求的应该不是对工具的使用,而是理解原理机制,创造工具,那么你就是牛B的。编程的目的是希望写出高效率高性能的东西,而机制对任何一种语言都实用,所以常说语言是相通的,你精通一门就精通大