KVO(Key-Value- Observing): 一对多, 观察者模式,键值观察机制,它提供了观察某 一属性变化的方法,极大简化了代码。
KVO底层实现:
- 使用了 isa 混写 isa-swizzling ,当一个对象( 假设是person对象, person的类是MYPerson)的属性值(假设 person 的 age 属性)发生改变时,系统会自动生成一个类,继承自 MYPerson : NSKVONotifying_MYPerson,在这个类的 setAge 方法里面调用 [super setAge:age] [self willChangeValueForKey:@"age"] 和 [self didChangeValueForKey:@"age"], 而这两个方法内部会主动调用监听者内部的 - (void)observeValueForKeyPath 这个方法
- 想要看到NSKVONotifying_MYPerson很简单, 在self.person.age = 20; 这里打断点, 在调试区域就能看到_person->NSObject- >isa=(Class)NSKVONotifying_MYPerson. 同时我们在 self.person = [[MYPerson alloc]init]; 后面打断点, 看到 _person->NSObject- >isa=(Class)MYPerson, 由此可见,在添加监听者之后 person 类型已经由 MYPerson 被改变成 NSKVONotifying_MYPerson
KVO的优点:
1.能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
2.能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象 (SKD对象)的实现;
3.能够提供观察的属性的最新值以及先前值;
4.用key paths来观察属性,因此也可以观察嵌套对象; 5.完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察
KVO的缺点:
1.我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;
2.对属性重构将导致我们的观察代码不再可用;
3.复杂的“IF”语句要求对象正在观察多个值,这是因为所有的观察代码通过一个方法来指向;
4.当释放观察者时需要移除观察者。
#####################################################################################
KVC(Key-Value-Coding):是键值编码, 一个对象在调用setValue的时候,使用字符串直接访问对象的属性.
KVC底层实现:
- 检查是否存在相应key的set方法,如果存在,就调用set方法。
- 如果set方法不存在,就查找_key的成员变量是否存在,如果存在就直接赋值。
- 如果_key没找到,就查找相同名称的key,如果存在就赋值。
- 如果没有就调用valueForUndefinedkey : 和 setValue:forUndefinedKey : 方法, 这些方法的默认实现都是抛出异常,我们可以根据需要重写它们
#####################################################################################
Delegate: 通常发送者和接收者的关系是直接的一对一的关系。
- 代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类, 而不需要获取到那些类的指针。
- 可以减少框架复杂度。消息的发送者(sender)告知接收者(receiver)某个事件将 要发生,delegate同意然然后发送者响应事件,delegate机制使得接收者可以改 变发送者的行为。
#####################################################################################
Notification: 观察者模式
- 通常发送者和接收者的关系是间接的多对多关系。
- 消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。
#####################################################################################
NotificationCenter Delegate KVO 之间的区别
- delegate效率肯定是比NSNotification高。
- delegate方法比notification更加直接,需要关注返回值,所以delegate方法往往包含should这个很传神的词。相反的,notification最大的特色就是不关心结果。所以notification往往用did这个词汇。
- 两个模块之间联系不是很紧密,就用notification传值,例如多线程之间传值用notificaiton。
- delegate只是一种较为简单的回调,且主要用在一个模块中,例如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底 层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能,例如 说 NavgationController 从 B 界面到A 点返回按钮 (调用popViewController方法) 可以用delegate比较好。
- KVO是一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。NotificationCenter和Delegate两种模式更加适合一个controller与任何其他的对象进行通信,而KVO更加适合任何类型的对象侦听, 另外一个任意对象的改变(这里也可以是controller,但一般不是controller)。这是一个对象与另外一个对象保持同步的一种方法,即当另外一种对象的状态发生改变时,观察对象马上作出反应。它只能用来对属性作出反应,而不会用来对方法或者动作作出反应。