KVC/KVO

KVC

问题:api

  1. 经过KVC修改属性会触发KVO么?
  2. KVC的赋值和取值过程是怎样的?原理是什么?

1. 什么是KVC?

Key-value coding是一种可以对属性/成员变量间接访问的机制,是一种非正式协议,和setter/getter方法比起来更加灵活,使用字符串做为key能够在运行期间改变。bash

常见的api函数

- (void)setValue:(id)value forKey:(NSString *)key;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

- (id)valueForKey:(NSString *)key; 
- (id)valueForKeyPath:(NSString *)keyPath;

复制代码

setValue:(id)value forKeyPath:(NSString *)keyPath 和 setValue:(id)value forKey:(NSString *)key 的区别ui

  • keyPath 至关于根据路径去寻找属性,一层一层往下找
  • key 是直接哪去属性的名字设置,若是按路径找会报错

2. valueForKey:的取值规则

  1. 接收器中若是有key访问器(-getKey, -key, or -isKey)直接访问 返回包装好的对象
  2. 没有访问器,使用接收器的类方法 +accessInstanceVariablesDirectly,若是为YES 则根据 _key, _isKey, key, or isKey 顺序查找 返回包装好的对象
  3. 未找到触发-valueForUndefinedKey:默认实现是抛出NSUndefinedKeyException异常

3. setValue:forKey:的赋值步骤

  1. 查找-setKey方法 有就直接调用
  2. +accessInstanceVariablesDirectly 返回YES 则依照 _key, _isKey, key, or isKey 顺序查找赋值
  3. -setValue:forUndefinedKey: 默认 抛出NSUndefinedKeyException

KVO

问题:spa

  1. iOS用什么方式来实现对一个对象的KVO?(KVO的本质是什么?)
  2. 如何手动出发KVO?
  3. 直接修改为员变量会触发KVO么?

答案

  1. iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)
利用runtime动态生成一个子类,而且让instance对象的isa指针指向这个全新的子类,当修改instance的属性时会调用Foundation的_NSSetXXXValueAndNotify函数,在函数中
- willChangeValueForKey:
- 父类原来的setter
- didChangeValueForKey:
内部会触发监听器(Oberser)的监听方法(observeValueForKeyPath:ofObject:change:context:)
复制代码
  1. 如何手动触发KVO?
手动调用willChangeValueForKey:和didChangeValueForKey:
复制代码
  1. 直接修改为员变量会触发KVO么?
不会触发KVO,由于直接修改为员变量并无走set方法
复制代码
  1. 经过KVC修改属性会触发KVO么?
会触发KVO,如上流程图
复制代码
  1. KVC的赋值和取值过程是怎样的?原理是什么?
本站公众号
   欢迎关注本站公众号,获取更多信息