简介
KVO(键值监听),即 Key-Value Observing, 是Objective-C 对观察者设计模式的一种实现。它提供一种机制,当指定的对象的属性被修改后(执行了setter 或 KVC 赋值),对象就会接受到通知。
应用
当某个对象的某个属性值改变时,用KVO监听。
示例
1、模型创建
在.h中
@interface PDcar : NSObject
@property (nonatomic,assign) int num; // 属性
@end
2、在 VC 中监听并响应属性改变
@interface ViewController ()
@property (nonatomic,strong)PDcar *myCar; //声明了car属性
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.myCar = [[PDcar alloc] init];
//设置监听
[self.myCar addObserver:self forKeyPath:@"num" options:
NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
3、实现监听回调方法
// 只要object的keyPath属性发生变化,就会调用此方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change context:(void *)context{
// 判断是否为self.myCar的属性“num”:
if([keyPath isEqualToString:@"num"] && object == self.myCar) {
// 响应变化处理
self.label.text = [NSString stringWithFormat:@"当前的num值为:%@",
[change valueForKey:@"new"]];
//change的使用:上文注册时,枚举为2个,因此可以提取change字典中的新、旧值的这两个方法
NSLog(@"oldnum:%@ ----newnum:%@",[change valueForKey:@"old"],
[change valueForKey:@"new"]);
}
}
4、注销监听
-(void)dealloc{
// 移除KVO
[self removeObserver:self forKeyPath:@"num" context:nil];
}
注意!同一个属性不能重复removeObserver,否则会出问题。
监听数组
http://www.cnblogs.com/XYQ-208910/p/6096186.html
与Notification(通知)、代理的区别
- notification 比 KVO 多了发送通知的一步。
两者都是一对多,但是对象之间直接的交互,notification 明显得多,需要notificationCenter 来做为中间交互。而 KVO 如我们介绍的,设置观察者->处理属性变化,至于中间通知这一环,则隐秘多了,只留一句“交由系统通知”,具体的可参照以上实现过程的剖析。
notification 的优点是,监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,例如键盘、前后台等系统通知的使用也更显灵活方便。
和 delegate 一样,KVO 和 NSNotification 的作用都是类与类之间的通信。但是与 delegate 不同的是:
这两个都是负责发送接收通知,剩下的事情由系统处理,所以不用返回值;而 delegate 则需要通信的对象通过变量(代理)联系;
delegate 一般是一对一,而这两个可以一对多。另外需要注意的是,由于KVO方式的注入是在运行时而不是编译时实现的,如果给定的实例没有观察者,那么 KVO 不会有任何开销,因为此时根本就没有 KVO 代码存在。但是即使没有观察者,委托和 NSNotification 还是得工作,这也是KVO此处零开销观察的优势。