- 当一个object有观察者时,动态创建这个object的类的子类
- 对于每个被观察的property,重写其
set
方法 - 在重写的
set
方法中调用- willChangeValueForKey:
和- didChangeValueForKey:
通知观察者 - 当一个property没有观察者时,删除重写的方法
- 当没有observer观察任何一个property时,删除动态创建的子类
(2)代码说明:
KVC key valued coding 键值编码
1)使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。如该程序中的“23”.
KVO 缺陷
KVO 很强大,没错。知道它内部实现,或许能帮助更好地使用它,或在它出错时更方便调试。但官方实现的 KVO 提供的 API 实在不怎么样。
比如,你只能通过重写 -observeValueForKeyPath:ofObject:change:context: 方法来获得通知。想要提供自定义的 selector ,不行;想要传一个 block ,门都没有。而且你还要处理父类的情况 - 父类同样监听同一个对象的同一个属性。但有时候,你不知道父类是不是对这个消息有兴趣。虽然 context 这个参数就是干这个的,也可以解决这个问题 - 在 -addObserver:forKeyPath:options:context: 传进去一个父类不知道的 context。但总觉得框在这个 API 的设计下,代码写的很别扭。至少至少,也应该支持 block 吧。
[ super didReceiveMemoryWarning ];
/* 3. 移除 KVO */
[ self removeObserver : self forKeyPath : @"num" context : nil ];
1.KVC与KVO的不同?
KVC(键值编码),即Key-Value Coding,一个非正式的Protocol,使用字符串(键)访问一个对象实例变量的机制。而不是通过调用Setter、Getter方法等显式的存取方式去访问。
KVO(键值监听),即Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,对象就会接受到通知,前提是执行了setter方法、或者使用了KVC赋值。
2.和notification(通知)的区别?
notification比KVO多了发送通知的一步。
两者都是一对多,但是对象之间直接的交互,notification明显得多,需要notificationCenter来做为中间交互。而KVO如我们介绍的,设置观察者->处理属性变化,至于中间通知这一环,则隐秘多了,只留一句“交由系统通知”,具体的可参照以上实现过程的剖析。
notification的优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,例如键盘、前后台等系统通知的使用也更显灵活方便。
(参照通知机制第五节系统通知名称内容)
3.与delegate的不同?
和delegate一样,KVO和NSNotification的作用都是类与类之间的通信。但是与delegate不同的是:
这两个都是负责发送接收通知,剩下的事情由系统处理,所以不用返回值;而delegate 则需要通信的对象通过变量(代理)联系;
delegate一般是一对一,而这两个可以一对多。
4.涉及技术:
KVC/KVO实现的根本是Objective-C的动态性和runtime,以及访问器方法的实现;
总结:
对比其他的回调方式,KVO机制的运用的实现,更多的由系统支持,相比notification、delegate等更简洁些,并且能够提供观察属性的最新值以及原始值;但是相应的在创建子类、重写方法等等方面的内存消耗是很巨大的。所以对于两个类之间的通信,我们可以根据实际开发的环境采用不同的方法,使得开发的项目更加简洁实用。