KVC与KVO

KVC-键值编码(Key Value Coding)

  • 动态设置:
    • setValue:属性值 forKey:属性名(用于简单路径)
    • setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
  • 动态读取:
    • valueForKey:属性名(用于简单路径)
    • valueForKeyPath:属性名(用于复合路径)

KVC使用起来比较简单,但是它是如何查找一个属性进行读取的呢?具体查找规则(假设现在要利用KVC对a属性进行读取):

  • 如果是动态设置属性,则优先考虑调用setA方法,如果没有该方法则优先考虑搜索成员变量a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公有的都能正确设置_);
  • 如果是动态读取属性,则优先考虑调用a方法(a属性的getter方法),如果没有搜索到则会优先搜索成员变量a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取_);

KVO-键值监听(Key Value Observe)

在ObjC中使用KVO操作常用的方法如下:

  • 注册指定Key路径的监听器:addObserver:forKeyPath:options:context:
  • 删除指定key路径的监听器:removeObserver:forKeypath:removeObservser:forKeyPath:context:;
  • 回调监听:observeValueForKeyPath:ofObject:change:context:

KVO的使用步骤也比较简单:

  1. 通过addObserver:forKeyPath:opetions:context:为被监听对象(通常是数据模型)注册监听器
  2. 重写监听器的observeValueForKeyPath:ofObject:change:context:方法
// cc监听了aa的name属性的改变
[aa addObserver:cc forKeyPath:@"name" options: NSKeyValueObservingOptionOld context:nil];
// cc得实现监听方法
/**
 * 当监听到object的keyPath属性发生了改变
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"监听到%@对象的%@属性发生了改变, %@", object, keyPath, change);
}

区别与联系

  • KVC常见作用:给模型属性赋值
  • KVO常用作用:监听模型属性值的改变
  • KVC是路径访问的规范,KVO是观察某个变量的变化过程
  • KVC/KVO类似于代理,通知中心。都是一种通讯方法。

你可能感兴趣的:(KVC与KVO)