iOS KVO基础知识
1. 简介
KVO其实就对应设计模式的观察者模式,观察者能够观察其他对象(被观察者)的属性。当被观察者的属性发生变化时,观察者就会被告知该变化。
2. 适用场景
KVO能很方便的实现model和controller之间的通信。
3. 用法
- 添加观察者:
addObserver:forKeyPath:options:context:
- 实现观察相应方法:
observeValueForKeyPath:ofObject:change:context:
- 在观察者释放之前移除对象上的监听:
removeObserver:forKeyPath:
4. 实例
4.1 创建model:
ObserveObject.h:
@interface ObserveObject : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic) NSInteger age;
@end
4.2 创建被观察者
ObserveObject *observe = [[ObserveObject alloc] init];
observe.name = @"tom";
observe.age = 20;
4.3 添加观察者
[observe addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
4.4 实现监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"name"]) {
NSString *oldName = change[NSKeyValueChangeOldKey];
NSString *newName = change[NSKeyValueChangeNewKey];
NSLog(@"old name = %@, new name = %@",oldName,newName);
}
}
注:
change是一个字典,包含了一系列键-值。
- NSKeyValueChangeKindKey : 变化的类型
- NSKeyValueChangeNewKey : 变化后的值
- NSKeyValueChangeOldKey : 变化前的值
- NSKeyValueChangeIndexesKey : 在所有变化中的坐标
NSKeyValueChangeKindKey又包含了:
- NSKeyValueChangeSetting
- NSKeyValueChangeInsertion
- NSKeyValueChangeRemoval
- NSKeyValueChangeReplacement
如果接收到的观察者消息与当前的context不符,就需要把消息传给父类,直到寻找到对应的context。
如果一个消息传到了NSObject仍然没有找到它的观察者,那么就会抛出异常:NSInternalInconsistencyException
4.5 移除监听
[observe removeObserver:self forKeyPath:@"name" context:nil];