比如说如下的第一行KVC的代码,其实和第二行的普通代码是等效的:
[myClass setValue:@"Andy Yi" forKey:@"name"];
myClass._name = @"Andy Yi";
KVC的代码会被编译器处理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (myClass->isa,sel);
method(site, sel, @"Andy Yi", @"name");
这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候:
a. 首先根据方法名找到运行方法的时候所需要的环境参数。
b. 它会从自己isa指针结合环境参数,找到具体的方法实现的接口。
c. 再直接查找得来的具体的方法实现。
2、KVO提供了观察某一属性变化的方法,实现了两个对象之间的交互。这种观察-被观察模型特别适用于MVC这种架构的程序,比方说根据业务层面的某个属性值变化,则UI层的某个属性做出相应变化。熟悉KVO的朋友都知道,只有当我们调用KVC去访问key值的时候KVO才会起作用。所以肯定确定的是,KVO是基于KVC实现的。使用KVO一般需要做如下的几步:
a. 注册:
[myClass addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
myClass是被观察的对象;Observer是观察者的对象;keyPath就是要观察的属性值;options给你观察键值变化的选择;而context方便传输你需要的数据
b. 实现变化方法。此处注意,如果一个ViewController同时观察了多个对象,那么在这里一定要判断一下这个keypath是不是你需要处理的那个对象,如果需要的话,最好再用“isMemberOfClass”判断一下你的对象的类型是否正确,否则容易出错,友情提醒一下。
-(void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:@"_name"] && [object isMemberOfClass:[MyClass class]]) {
nameLabel.text = myClass.name;
}
}