参考文章:http://www.cnblogs.com/ChenYilong/archive/2012/11/16/2808610.html
1)kvc是KeyValue Coding的简称,键值编码。它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过getter,setter方法访问。
2)获取值:
valueForKey:传入nsstring属性的名字
valueForKeyPath:传入NSString属性的路径,xx.xx形式。
valueForUndefinedKey它的默认实现是抛出异常。可以重写这个函数做错误处理
3)修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setNilValueForKey当对非类对象属性设置nil时,默认抛出异常
4)一对多成员的情况
mutableArrayValueForKey:有序一对多关系成员 NSArray
mutableSetValueForKey:无序一对多关系成员 NSSet
kvc的实现分析:
KVC 运用了一个 isa-swizzling 技术。isa-swizzling 就是类型混合指针机制。
KVC 主要通过 isa-swizzling,来实现其内部查找定位的。isa 指针,就是 is a kind of 的意思,指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针和其它数据。
如下 KVC 的代码:
[person setValue:@"personName" forKey:@"name"];
就会被编译器处理成:
SEL sel = sel_get_uid("setValue:forKey:");
IMP method = objc_msg_lookup (person->isa,sel);
method(person,sel,@"personName",@"name");
其中:
SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。
IMP数据类型:他其实就是一个编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型。
KVC在调用方法setValue的时候
(1)首先根据方法名找到运行方法的时候所需要的环境参数。
(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。
(3)再直接查找得来的具体的方法实现。
这样的话前面介绍的KVO实现就好理解了
当一个对象注册了一个观察者,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。
所以isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。
这样只有当我们调用KVC去访问key值的时候KVO才会起作用。所以肯定确定的是,KVO是基于KVC实现的。