KVO (Key - Value Observing)

键-值观察者(key - value observing)是指当指定的对象的属性被修改时,允许对象接收通知的机制。
总的来说,也就是告诉一个对象,“我想要观察你的fido属性,如果它发生了变化,就通知我。当setFido: 方法被调用的时候,被观察的对象会发送消息告诉你,我的fido属性有一个新值了。”讨论KVO和讨论NSNotificationCenter时使用的语言很相似,二者底层实现原理很相似。

观察、回调

  1. 添加观察
  • 无论lastTime何时发生变化,都要通知我它改变的新值以及改变之前的旧值
    [被观察者 addObserver: 观察者
    forKeyPath: @"被观察者的某一属性"
    options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
    context: nil];
    实现被观察属性发生变化时的回调方法
- (void)observeValueForKeyPath:(NSString *)keyPath
                         ofObject:(id)object
                           change:(NSDictionary *)cahnge
                               context:(void *)context {
    NSString *oldValue = [change objectForKey:NSKeyValueChangeOldKey];
        NSString *newValue = [change objectForKey:NSKeyValueChangeNewKey];
}
  1. 在KVO中使用context
    注意: 当在代码中将某个对象注册为观察者时,你需要传递指针为context。当接收变化的通知时,context会随通知一起发送。context可以用来回答:“这真的是我需要的通知吗?”例:
static int contextForKVO;
[被观察者 addObserver: self 
               forKeyPath: @"fido"
                options:0
                         context: &contextForKVO];
- (void)observeValueForKeyPath:(NSString *)keyPath
                         ofObject:(id)object
                           change:(NSDictionary *)cahnge
                               context:(void *)context {
    // 这是不是我的?
    if (context != &contextForKVO) {
        // 将它传递给父类
        [super observerValueForKeyPath:keyPath];
    } else {
        // 处理变化
    }
}
  1. 显式触发通知
    如果使用存取方法来设置属性,那么系统就会自动通知观察者。但由于某种原因,你选择不适用存取方法呢?这时可以通过willChangeValueForKey:和didChangeValueKey:方法通知系统木某个属性的值即将/已经发生变化。
NSDate *now = [NSDate date];
[self willChangeValueForKey:@"lastTime"];
_lastTime = now;
[self didChangeValueForKye:@"lastTime"];
  1. 独立的属性
    如果你不想观察_lastTime而想观察_lastTimeString,可以通过一个类方法来做这项工作。
+ (NSSet *)keyPathsForValuesAffectingLastTimeString {
   retutn [NSSet setWithObject:@"lastTime"];
}

注:摘自《Objective-C编程》(第2版)page 301

你可能感兴趣的:(KVO (Key - Value Observing))