KVO listen 以类 CLPerson 为例 age 属性 未监听 CLPerson isa 指向 CLPerson 类对象 class 方法返回自己 KVO监听之后 CLPerson isa指针指向了一个叫NSKVONotifying_CLPerson的class对象 class 方法被重写,返回 CLPerson 重写了setAge方法 重写了 dealloc 增加了_isKVOA方法 监听之后元类是不一样的, 并且一个类添加监听之后,新增的KVO类并不会动态 删除,会留在缓存 重写 setAge 调用_NSSetIntValueAndNotify()函数 调用[self willChangeValueForKey:@"age"]; 再调用父类(CLPerson)的setAge方法[super setAge:age]; [self didChangeValueForKey:@"age"]; [self didChangeValueForKey:@"age"];方法里面对监听器进行通知,也就是回 调它的监听代理方法 总结 iOS用什么方式实现对一个对象的KVO?(KVO的本质) 1.利用Runtime API为被监听对象动态生成一个子类,并且让instance对象的isa 指向这个新的子类 2.在新的子类中重写属性的setter方法。当instance对象属性被修改的时候,该 setter方法被调用 3.在上述的setter方法里面,会调用Foundation对象的 _NSSetXXXValueAndNotify函数,该函数内部的主要逻辑是 3.1调用willChangeValueForKey: 3.2调用父类(也就是instance对象被监听之前,isa所指向的class)的setter 方法,进行成员变量赋值 3.3调用didChangeValueForKey:方法,该方法内部会触发监听器 (observer)的监听方法(observeValueForKeyPath: ofObject: change: context:) 如何手动触发KVO 手动调用willChangeValueForKey:和didChangeValueForKey:即可 直接修改成员变量会触发KVO吗? 不会触发KVO 触发KVO的条件是通过属性值修改,触发了setter方法,从而触发KVO回调方 法,因此直接修改属性对应的成员变量值,不会触发KVO。