KVC定义:KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:
动态设置: setValue:属性值forKey:属性名(用于简单路径)
setValue:属性值forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
动态读取: valueForKey:属性名
valueForKeyPath:属性名(用于复合路径)
KVC使用规则:
如果是动态设置属性,则优先考虑调用setA方法,如果没有该方法则优先考虑搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设置);
如果是动态读取属性,则优先考虑调用a方法(属性a的getter方法),如果没有搜索到则会优先搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取);
iOS 开发中KVC的使用场景:
动态的取值和设值访问和修改私有变量 model和字典的转换修改一些控件的内部属性操作集合高阶消息传递(栗子:(UIAlertAction的私有属性_titleTextColor) [cancelAction setValue:[UIColor yellowColor] forKey:@"_titleTextColor"];)
KVO定义:KVO即Key-Value Observing,翻译成键值观察。它是一种观察者模式的衍生。其基本思想是,对目标对象的某属性添加观察,当该属性发生变化时,通过触发观察者对象实现的KVO接口方法,来自动的通知观察者。
KVO其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。
注意事项:观察者观察的是对象的属性,只遵循KVO变更属性值的方法才会执行KVO的回调方法,如果赋值没有通过setter方法或者KVC,直接修改属性的值,是不会触发KVO机制的,也不会调用回调的方法;
使用KVO操作常用的方法如下:
注册指定Key路径的监听器:addObserver: forKeyPath: options: context:
删除指定Key路径的监听器:removeObserver: forKeyPath、removeObserver: forKeyPath: context:
回调监听:observeValueForKeyPath: ofObject: change: context:
KVO的使用步骤:
通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
重写监听器的observeValueForKeyPath: ofObject: change: context:方法
举个栗子:
// 添加观察者
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
// 监听加载进度
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"]) {
if (object == self.webView) {
//在这里进行监听到变化后的操作
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
//移除观察者
-(void)dealloc {
if (self.webView) {
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
}
}
好文推荐:KVC 详解了解 点击 https://blog.csdn.net/u013983033/article/details/84071483
KVO 详解了解 点击 https://blog.csdn.net/u013983033/article/details/83104834