KVC
键值编码(Key-Value Coding)是Cocoa的一个特性,它允许你通过对象名设置和获取对象的值。
KVC特性
- 如果尝试给一个并不存在于你定义的类的键设置一个值,该KVC系统将会抛出一个异常,因为运行时不知道将该值存储在哪里。
- 在KVC中没有访问保护,当私有变量被访问时,KVC依然有效。
KVC不是旨在更换访问方法,而是提供一个更为灵活的方式设置和获取对象的值。
KVO
在MVC模式下,控制器如何得知何时更新视图?有两种选项:
- 反复检查模型,观察是否有任何更改。
- 等待模型向控制器发送通知。
第一种选项的实现最简单,创建一个定时器,定期获取模型中的最新值,并将其提供给视图。(浪费CPU资源)
要解决此问题,Cocoa提供了一种功能,KVO。KVO允许对象注册为当另一个对象更改它的一个属性的值时收到通知。
KVO有助于简化注册通知的过程以及通知任何需要被告知变化的对象。任何对象的任何属性都可以被观察,只要该属性的名称符合KVO。(前提是执行了setter方法或者使用了KVC赋值)。
添加观察者:
[self.model addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
当属性发生变化时,系统会回调该方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"title"] && (object == self.model)) {
// 获取新值,更新label。
NSString *newTitle = [change objectForKey:NSKeyValueChangeNewKey];
self.textLabel.text = newTitle;
NSString *oldTitle = [change objectForKey:NSKeyValueChangeOldKey];
NSLog(@"%@", oldTitle);
}
}
另外,如果不使用OC属性,或者重写了一个属性的setter方法,则需要手动通知系统所做的更改。
- (void)setTitle:(NSString *)title {
[self willChangeValueForKey:@"title"];
_title = title;
[self didChangeValueForKey:@"title"];
}