KVO
Key-Value Observing,“键值监听”:用于监听某一对象属性值的改变。
某一对象被监听后,系统利用 Runtime API 对该对象的原始类动态生成一个 “NSKVONotifying_CPPerson” 子类,并且让 instance 对象的 isa 指针指向这个子类。
在新生成的这个子类中会重写父类的 setAge:、class、dealloc、_isKVOA 四个方法。
当被监听对象的属性值发生改变后,会在 setAge: 方法中调用 NSFoundation 的 “_NSSetIntValueAndNotify” 函数。且在该函数内部重写了父类的 willChangeValueForKey:、setAge:、didChangeValueForKey:方法。
并且在 didChangeValueForKey:方法中出发监听器 Observe 的监听方法 “observeValueForKeyPath: ofObject: change: context:”。
本质:
由于 KVO 的本质是重写了原始类的
Setter 方法,所以像直接修改成员变量是不会触发监听方法的。若想手动触发监听器的监听方法:手动执行
willChangeValueForKey:、didChangeValueForKey:方法。![[100][100]](/2018/05/31/浅析KVO、KVC/1.png)
KVC
Key-Value Coding,“键值编码”:可以通过某一个 key 来访问对应的属性。
KVC 不管有没有调用 setter 方法,都会触发 KVO 的监听方法。因为它会手动触发监听。
赋值操作:setValue: forKey:
首先会寻找
setAge:、_setAge:两个方法的实现。若没有,会通过
accessInstanceVariablesDirectly方法判断是否允许访问成员变量,若为 YES,则访问的顺序为_age、_isAge、age、isAge。
![[100][100]](/2018/05/31/浅析KVO、KVC/2.png)
取值操作:valueForKey:
首先会寻找
getAge:、age:、isAge:、_age:四个方法的实现。若没有,同上。
![[100][100]](/2018/05/31/浅析KVO、KVC/3.png)


