面试会经常问到上述几个模式的区别,今天进行汇总:
一:他们之间的区别
observeValueForKeyPath:ofObject:change:context:
2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单
3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息
4.通知的发送者和接受者都不需要知道对方。可以指定接收通知的具体方法。通知名可以是任何字符串。
1.不能传大量数值;
2.在编译期不会检查通知是否能够被观察者正确的处理;
3.在释放注册的对象时,需要在通知中心取消注册;
4.在调试的时候应用的工作以及控制过程难跟踪;
5.需要第三方对喜爱那个来管理controller与观察者对象之间的联系;
6.controller和观察者需要提前知道通知名称、UserInfo dictionary keys。如果这些没有在工作区间定义,那么会出现不同步的情况;
7.通知发出后,controller不能从观察者获得任何的反馈信息。
8.如果通知过多,会造成通知的管理复杂,如果管理不好,你会接收到莫名其妙的消息,而无法追踪
通知的使用场合:
1.通知是全局的,而且是同步的,如果你要全局发送消息,并且做的事情时间不长,不会阻塞线程的话,建议使用。
2.如果一个通知的发送者有多个接受者,而且接受的位置完全不确定,那么这种情况下用通知是比较好的方式。
具体代码:
1.能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
2.能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;
3.能够提供观察的属性的最新值以及先前值;
4.用key paths来观察属性,因此也可以观察嵌套对象;
5.完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察
1.我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;
2.对属性重构将导致我们的观察代码不再可用;
3.复杂的“IF”语句要求对象正在观察多个值。这是因为所有的观察代码通过一个方法来指向;
4.当释放观察者时不需要移除观察者。
KVO使用场合:你需要监听UITableview的content offset,那么当tableview滑动的时候,就会不停的收到contentoffset point值。你要监听某一对象的值的时候,建议使用。
1.非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。
2.如果delegate中的一个方法没有实现那么就会出现编译警告/错误
3.协议必须在controller的作用域范围内定义
4.在一个应用中的控制流程是可跟踪的并且是可识别的;
5.在一个控制器中可以定义定义多个不同的协议,每个协议有不同的delegates
6.没有第三方对象要求保持/监视通信过程。
7.能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller
代理的缺点:
1.需要定义很多代码:1.协议定义;2.controller的delegate属性;3.在delegate本身中实现delegate方法定义
2.在释放代理对象时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash
3.在一个controller中有多个delegate对象,并且delegate是遵守同一个协议,但还是很难告诉多个对象同一个事件,不过有可能。
代理的使用场合:如果实现的接口比较多的话,建议用代理,如UITableview。
在ClassB的头文件(ClassB.h)中定义一个代理如下:
@interface ClassB
@property (nonatomic, unsafe_unretained) id<ClassBDelegate> delegate;
@end
这样,当我们在ClassB的实现文件(ClassB.m)中遇到想让别的类(如 ClassA)处理的问题时,就可以这样
[self.delegate methodOne];
[self.delegate methodTwo:@"需要传递的值"];
还有不足之处,日后总结。