iOS中的KVO和KVC
2020-07-13 本文已影响0人
it小小菜鸟
一、KVO
KVO的全称是 Key-Value Observing 俗称 “键值监听”,可以用于监听某个对象属性值的改变
KVO本质:
利用RunTime API动态生成一个子类,并且让instance对象的isa指针指向这个全新的子类class对象;
当修改instance对象的属性时,会调用Foundation中的 _NSSetXXXValueAndNotify函数:
- willChangeValueForKey:
- super setXXX: 父类原来的setter方法
- didChangeValueForKey:
内部会触发监听器(Observe)的监听方法(observeValueForKeyPath:ofObject:change:context:)
如何手动触发KVO:
手动调用 willChangeValueForKey: 和 didChangeValueForKey: 方法
直接修改成员变量会触发KVO吗?
不会,因为不会调用setter方法,就不会调用相关的方法。
二、KVC
KVC的全称是 Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性
-
常见API有:
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (void)valueForKeyPath:(NSString *)keyPath;
- (void)valueForKey:(NSString *)key;
-
key和keyPath的区别:
key就只支持当前类的属性,如:forKey:@"xxx"
keyPath支持路径查找,如:forKeyPath:@"xxx.xxx.xxx"
-
setValue:ForKey: 设置值的流程:如下图
截屏2020-07-13 下午5.53.09.png
+accessInstanceVariablesDirectly默认返回YES -
valueForKey: 取值的流程:如下图
截屏2020-07-13 下午6.17.40.png
通过KVC设置属性能触发KVO吗?
会触发KVO:
- 如果有setter方法的话,会直接调用setter方法,从而触发KVO
- 如果没有setter方法,KVC内部也会调用willChangeValueForKey:和didChangeValueForKey:从而触发KVO方法