KVO全称Key Value Observing.直译为键值观察。KVO主要用于视觉交互方面,比如当某些数据变化了,界面的显示也跟着需要变化,那就要简历数据和界面的关联。
KVO就定义了这种机制,当被观察对象特定的属性变化的时候会通知其观察对象。
方法定义:
变化的通知
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
方法调用时机:当给定对象的特定的keyPath上面对应的值变化的时候,消息会发送给接收者。
参数的解释:
keyPath:与object相关联的,指向变化的值
object:keyPath的源对象
change:描述与object相关联的keyPath对应属性变化描述的一个dictionary对象。
context:当接收者被注册过后能接收key-value 观察通知后所提供给的值。
********要注意:接收者能够接收消息的前提是必须被注册为特定对象特定****keyPath****上的观察者才行。********
********注册成为观察者********
注册一个观察者来接收与key-path相关的接收者发送的KVO通知。
方法:
-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
参数
anObserver:一个注册KVO通知的对象,观察者必须实现key-value 观察方法observerValueForKeyPath:ofObject:change:context:
keyPath:与接收者要被观察属性相关的key path,不能为nil
options:包含在观察通知中的一个NSKeyValueObservingOptions的值的组合
context:任意的一个值传递给方法observeValueForKeyPath:ofObject:change:context:
注意
不管是接收者还是观察者,都是retained的。在使用KVO时候,调用上面方法的对象后,必须调用removeObserver:forKeyPath:
或removeObserver:forKeyPath:context:
方法
最后要注意的是,要观察的值是要通过KVC方法进行设置才能通过KVO接受,否则不行。即xxx setValue: forKey:
这样子的方法。
- (id)initWithStudent:(Student *)student {
if (self = [super init]) {
_student = student;
[_student addObserver:self forKeyPath:@"courseName" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:@"new observer"];
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"courseName"]) {
NSLog(@"课程变化了");
NSLog(@"新课程是:%@,老课程是%@", [change objectForKey:@"new"], [change objectForKey:@"old"]);
NSLog(@"context is %@", context);
}
}
- (void)dealloc {
[self.student removeObserver:self forKeyPath:@"courseName" context:@"new observer"];
}