一、使用方法
1、注册
NSKeyValueObservingOptionNew:change字典包括改变后的值
NSKeyValueObservingOptionOld: change字典包括改变前的值
NSKeyValueObservingOptionInitial:注册后立刻触发KVO通知
NSKeyValueObservingOptionPrior:值改变前是否也要通知(这个key决定了是否在改变前改变后通知两次)
//监听姓名属性的变化
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
2、实现回调方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject: (id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"name"]) {
NSLog(@"Name is changed new = %@",[change objectForKey:NSKeyValueChangeNewKey]);
}else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
3、移除通知
- (void)dealloc
{
[self.person removeObserver:self forKeyPath:@"name" context:nil];
}
二、经典的KVO使用场景(model与view同步)
- (void)testKVO
{
Person *person = [Person new];
self.person = person;
[person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
//实现回调
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"age"]) {
NSString *old = [change objectForKey:NSKeyValueChangeOldKey];
NSString *nw = [change objectForKey:NSKeyValueChangeNewKey];
// self.oldValueLB.text = old;
self.valueLB.text = nw;
NSLog(@"%@ %@",old,nw);
}else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];;
}
}
//移除
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.person removeObserver:self forKeyPath:@"age" context:nil];
}
- (IBAction)button:(id)sender {
self.person.age = [NSString stringWithFormat:@"%u",arc4random()%100];//取余
}
三、手动设置KVO通知
- (void)setAge:(NSString *)age
{
if ([age integerValue] < 18) {
NSLog(@"未成年");
}
[self willChangeValueForKey:age];
_age = age;
[self didChangeValueForKey:age];
}
//不自动
+ (BOOL)automaticallyNotifiesObserversOfAge
{
return NO;
}