KVC:键值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。
KVO:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
example:
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSD ictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"highlighted"] ) { NSLog(@"测试KVO");
}
}
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSD ictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"highlighted"] ) { NSLog(@"测试KVC");
}
}
对于系统是根据keyPath去取的相应的值发生改变,理论上来说是和kvc机制的道理一样。对于kvc机制如何通过key寻找到value:
"当通过KVC调用对象时,比如:[self valueForKey:@"someKey"]时",程序会自动试图通过几种不同的方式解析这个调用。首先查找对象是否带有someKey这个方法,如果没找到,就会继续查找对象是否带有someKey这个实例变量(iVar),如果还没找到,程序会继续调用valueForUndefinedKey: 方法。如果这个方法还是没有被实现的话,程序会抛出一个NSUnderfinedKeyException异常错误。
KVO/KVC
(1)如何调用私有变量,如何修改系统的只读属性,KVC的查找顺序
KVC在某种程度上提供了访问器的替代方法。只要有可能,KVC尽量在访问器方法的帮助下工作。为了设置或者返回对象属性,KVC按顺序使用:
1.检查是否存在-<key>.-is<key>或者get和set方法,将大写key字符串的第一个字母,并与Cocoa的方法名保持一致;
2.如果方法不行,则检查名为_<key>,_is<key>,_get<key>,_set<key>
3.如果没有找到访问器方法,可以尝试直接访问实例变量,实例变量可以是名为:_<key>
4.如果仍未找到,则调用valueForUndefinedKey和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。
(2)kvo的实现机制
当某个类的对象第一次观察时,系统会在运行时动态地创建该类的一个派生类,在这个派生类中重写class方法。然后系统将这个对象的isa指针指向这个新诞生的派生类,因此这个对象成为该派生类的对象,因而在该对象上对setter的调用就会调用重写的setter,从而激活键值通知机制。此外,派生类还重写了dealloc方法来释放资源。
(3)KVO计算属性,设置依赖键
监听的某个属性可能会依赖于其他多个属性的变化,不管所依赖的那个属性发生了变化,都会导致计算属性的变化。
(4)kvo使用场景
1.实现上下拉刷新控件 contentoffset
2.webview混合排版 contentsize
3.监听模型属性实时更新UI