1. KVO 是什么?
KVO是OC观察者模式的一种实现(另一种是NSNotification);
KVO提供一种机制, 制定一个被观察对象(例:Person类), 当对象某个属性(例:name)发生改变时, 对象会获得通知, 并作出相应的处理; 且不需要给被观察对象添加任何代码.
在MVC架构下的项目, KVO机制很适合实现Model和View之间的通讯.
例: 在model_B创建属性数据, 在控制器中创建观察者, 一旦属性数据发生改变观察者就收到通知, 通过KVO在控制器使用回调方法实现view_C的更新.
2. 基本实现原理
当观察某对象A时, KVO机制会动态创建一个对象A的子类NSKVONotifying_A, 并为这个新类重写被观察属性name(即keyPath)的setter方法. setter方法随后负责通知观察对象属性的变化.
3. 特点
观察者观察的是属性, 只有遵循KVO变更属性的方式才会执行KVO的回调方法, 即是否执行科setter方法或者是否使用了KVC赋值. 如果没有, 而是直接修改属性对应的成员变量(_name = @"花花")是不会触发KVO机制的. 所以, 使用KVO机制的前提是遵循KVO的属性设置方式来变更属性值.
4. 应用
self.myKVO=[[myKVO alloc]init];
/*1.注册对象myKVO为被观察者: option中,
NSKeyValueObservingOptionOld 以字典的形式提供 “初始对象数据”;
NSKeyValueObservingOptionNew 以字典的形式提供 “更新后新的数据”; */
[self.myKVO addObserver:selfforKeyPath:@"num" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
/* 2.只要object的keyPath属性发生变化,就会调用此回调方法,进行相应的处理:UI更新:*/
-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary<NSString*,id>*)change context:(void*)context{
// 判断是否为self.myKVO的属性“num”:
if([keyPath isEqualToString:@"num"]&&object==self.myKVO){
// 响应变化处理:UI更新(label文本改变)
self.label.text=[NSString stringWithFormat:@"当前的num值为:%@",[change valueForKey:@"new"]];
//change的使用:上文注册时,枚举为2个,因此可以提取change字典中的新、旧值的这两个方法
NSLog(@"\\noldnum:%@ newnum:%@",
[change valueForKey:@"old"],
[change valueForKey:@"new"]);
}
}
/*KVO以及通知的注销,一般是在-(void)dealloc中编写。
至于很多小伙伴问为什么要在didReceiveMemoryWarning?因为这个例子是在书本上看到的,所以试着使用它的例子。
但小编还是推荐把注销行为放在-(void)dealloc中。(严肃脸😳)
*/
-(void)didReceiveMemoryWarning{[superdidReceiveMemoryWarning];
/* 3.移除KVO */
[self.myKVO removeObserver:selfforKeyPath:@"num"context:nil];
}
//按钮事件
-(IBAction)changeNum:(UIButton*)sender{
//按一次,使num的值+1
self.myKVO.num=self.myKVO.num+1;
}
网友评论