KVO
- KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。KVO其实也是“观察者”设计模式的一种应用。
kvo的使用
-
1: 先创建一个nsobject类
#import <Foundation/Foundation.h>@interface kvoCatagory : NSObject @property(nonatomic,assign)NSInteger kvoNum; @end #import "kvoCatagory.h" @implementation kvoCatagory @synthesize kvoNum; @end
-
2:实现kvo监听
#import "ViewController.h" #import "kvoCatagory.h" @interface ViewController () @property(nonatomic,strong)UILabel *label; @property(nonatomic,strong)kvoCatagory *catagory; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _catagory = [[kvoCatagory alloc]init];
UIButton *btn = [UIButton buttonWithType: UIButtonTypeCustom ];
btn.frame = CGRectMake(100, 100, 100, 40);
[btn setTitle:@"btnclick" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
/*1.注册对象myKVO为被观察者:
option中,
NSKeyValueObservingOptionOld 以字典的形式提供 “初始对象数据”;
NSKeyValueObservingOptionNew 以字典的形式提供 “更新后新的数据”;
*/
[self.catagory addObserver:self forKeyPath:@"kvoNum" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
/* 2.只要object的keyPath属性发生变化,就会调用此回调方法,进行相应的处理:UI更新:*/
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if([keyPath isEqualToString:@"kvoNum"] && object == self.catagory)
{
// // 响应变化处理:UI更新(label文本改变)
// self.label.text = [NSString stringWithFormat:@"当前的num值为:%@",[change valueForKey:@"new"]];
//
//上文注册时,枚举为2个,因此可以提取change字典中的新、旧值的这两个方法
NSLog(@"\noldnum:%@ newnum:%@",[change valueForKey:@"old"],[change valueForKey:@"new"]);
}
}
-(void)btnClick:(UIButton *)sender{
//按一次,使num的值+1
self.catagory.kvoNum = self.catagory.kvoNum + 1;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
/* 3.移除KVO */
[self.catagory removeObserver:self forKeyPath:@"kvoNum" context:nil];
}
KVO 的底层实现:
- KVO 的底层实现是通过Objective-C强大的运行时(runtime)实现的。
- 当你第一次观察一个对象object时,runtime 会动态地创建一个继承自该对象object所属类的子类,类名格式为为NSKVONotifying_[subclass名],同时保存注册观察者方法中的所有参数,包括监听者、路径、枚举、携带参数等。
- 这个新创建的子类重写了所有被观察属性的 setter 方法,并且在内部给观察者发送通知,通知所有观察对象值的更改。
- 最后把这个对象object的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么类型的 ) 指向这个新创建的子类,此时这个被观察的对象 object 就神奇地变成了新的子类的实例。