type
status
date
slug
summary
tags
category
icon
password
手动禁止 KVO
手动触发 KVO
Swift 中的计算型属型和存储型属性均可观察
OC 中的成员变量不可观察(不做示例,下方说明 KVO 实现原理)

原理

在 Person 对象添加观察者后
系统会动态生成一个继承于 Person 类的子类 NSKVONotifying_Person,并把 person 对象的 isa 指针指向 NSKVONotifying_Person(之前 isa 指针指向 Person 类)
该类不会在
后消失,但是在 remove 后 person 会回归 Person 类。
NSKVONotifying_Person类会实现四个方法
isKVOA// 判断是否为 KVO 动态生成的类
dealloc// 析构函数
calss// 类函数
setName // 重写观察属性的 setter 方法
OC 成员变量无法生成 setter 方法,故不能适用于 KVO
但 OC 成员变量可用 KVC 触发 KVO
setter 方法中,系统会调用
方法去通知观察者
坑:
为什么 KVO 需要销毁
正常情况不需要销毁,被观察对象释放就可以了
但是如果被观察对象生命周期大于观察者,如被观察者为单例,存在全局区,进程结束释放。
此时观察者释放而没有移除的话,值改变时依然会像观察者发送消息,观察者已经释放,所以 Crash
为什么说 KVO 基于 KVC?
1、
当使用KVO观察某个类属性时,会为该类创建一个子类,子类重写 setter 方法时,跟 KVC set 时的搜索顺序是一样的,都是先搜索 set<Key>,然后在搜 _set<Key>。对于KVC,若不存在会有后续操作,参考
2、在为observe的change字典里的old和new赋值时,用到了KVC的valueForKey:
3、苹果 KVO 文档里的一句话
KVCCopy On Write