您的当前位置:首页监听者模式之KVO的总结

监听者模式之KVO的总结

2024-12-13 来源:哗拓教育

一、使用方法
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;
}
显示全文