KVO - KVC 从根本原理透析

一.KVO

KVO的全称为Key-Value Observing,也就是我们常说的键值监听。通过KVO我们可以监听某个对象的属性的改变

1.KVO的使用

1.给对象添加KVO监听

NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.person addObserver:self forKeyPath:@"age" options:options context:@"context"];

2.当监听对象的属性值发生改变的时候会调用下面的方法

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"监听到%@的%@属性值改变了 - %@ - %@", object, keyPath, change, context);
}

3.当内存销毁的时候移除KVO监听

- (void)dealloc {
   [self.person removeObserver:self forKeyPath:@"age"];
}

2.KVO的本质

  • KVO的本质其实是利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类。
  • 所以当我们修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数,即:
    . willChangeValueForKey:
    . 父类原来的setter
    .didChangeValueForKey:
    接下来内部会触发监听器(Oberser)的监听方法(observeValueForKeyPath:ofObject:Change:Context:)

面试问题:

  • 如何手动出发KVO
    只要手动调用willChangeValueForKey和didChangeValueForKey:方法即可

  • 直接修改成员变量会触发KVO吗?
    并不会,因为本质是动态生成一个子类中,调用上诉的三个方法,但是直接修改并没有调用。

二.KVC

  • KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性
  • 常见的API有
    . (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
    . (void)setValue:(id)value forKey:(NSString *)key;
    . (id)valueForKeyPath:(NSString *)keyPath;
    . (id)valueForKey:(NSString *)key;

你可能感兴趣的:(KVO - KVC 从根本原理透析)