KVO:(Key-Value-Observer)键值观察者,是观察者设计模式的一种具体实现。
在我们编程中,很多时候,需要对一些对象进行监听,一旦这个对象发生变化,其他的对象就需要对其作出反应,KVO 就可以完成这项任务。
1、KVO 的触发机制与使用步骤
KVO触发机制:
一个对象(观察者),监测另一对象(被观察者)的某属性是否发生变化,若被监测的属性发生的更改,会触发观察者的一个方法(方法名固定,类似代理方法)
KVO使用步骤:
1、注册观察者(为被观察者指定观察者以及被观察属性)
2、实现回调方法
3、触发回调方法(被观察属性发生更改)
4、移除观察者
2、KVO 的基本用法
下面举一个小例子来说明 KVO 的基本用法:
1)、我们先来创建一个Person类:
#import <Foundation/Foundation.h>
@interface Person : NSObject
// 姓名
@property(nonatomic, copy) NSString *name;
@end
2)、在 ViewController.m 中创建 Person 类,并添加观察者对其监听:
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化Person
self.person = [Person new];
_person.name = @"孙悟空";
// 添加观察者
[_person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:(__bridge void *)self];
// 添加改变person值得手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self.view addGestureRecognizer:tap];
}
3)、实现 tapAction 方法:
- (void)tapAction:(UITapGestureRecognizer *)sender {
_person.name = @"猪八戒";
}
4)、实现 KVO 方法:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
// keyPath 是观察的属性
NSLog(@"keyPath = %@", keyPath);
// object 被观察的对象
NSLog(@"%@", object);
// change 新旧值
NSLog(@"change = %@", change);
// 对其变化进行判定
if ([change[NSKeyValueChangeNotificationIsPriorKey] boolValue]) {
NSLog(@"值改变之前");
} else {
NSLog(@"值改变之后");
}
// context 的作用就是传值
ViewController *vc = (__bridge ViewController *)context;
vc.view.backgroundColor = [UIColor greenColor];
}
通过以上方法就可以实现:触摸屏幕,改变person.name的值,从而调用 KVO,使得背景屏幕变成绿色。
在MVC中,KVO的使用场景通常是,M与C通信,M发生变化通知C。其中M是被观察者,C是观察者。
另外需要注意一点:观察者销毁之前,移除观察者,否则会出现程序异常(给已经销毁的对象发送消息)