代理<delegate>、通知<NSNotification>、KVO三者之间的区别

我们在开发iOS应用时,会经常遇到一些常见的问题:在不过分要求耦合的前提下,各个Controller之间是怎么进行通信的,随着在iOS应用开发的过程中出现了以下三种普通的方法来实现这种通信,从而达到各个Controller之间的通信。


1、代理<delegate>,也就是我们俗称的“委托”;
2、通知中心<Notification Center>;
3、键值监听或者是键值观察<Key Value Observing>;
 
在平时的开发中,以上的三种模式都可以用来将一个对象的事件传递给另一个对象,而且不需要他们有耦合的现象。以上的三种情况都是对象来通知某个事件发生的方法,也可以说是准许其他的对象能接收到这个事件的响应的方法;对于一个对象来说,这些事最普通而且是必须要完成的任务,如果没有通信,各个Controller将不能被整合到整个的iOS应用当中。在开发中,如果我们在写的程序中让他们耦合了,那么我们将不能对他们进行复用,这样我们就完全失去了对应用程中一个独立的组件的控制了。
 
接下来,就针对以上的三种通信方式进行进行简单的一些阐述:《个人理解,仅供参考哈》
我们在写程序的时候,都应该注意到了,在不断的使用“delegate”,而且是应用到了整个的SDK中,<delegate>并不是iOS应用程中特有的模式,而是依赖于我们的编程背景;至于它的优势和为什么会被经常的用到,这些都也许都不是很明显的:
delegate的基本特征是什么:
一个Controller定义了一个协议,该协议描述了一个delegate对象为了能响应一个Controller的事件而必须要完成的事情。简单的说就是“我们去一个公司上班,就必须要遵守该公司的一些规章制度,联系到程序中就是如果某个ControllerA想成为ControllerB的delegate,那么这个ControllerA就必须要遵守ControllerB的协议,而且要实现他必须实现的方法<@required>,因为协议中的方法有的是必须实现的,有的是可选的<@optional>并不一定要都实现”。delegate可以是任何的对象类型,所以Controller不会与某一个对象进行耦合。
 
代理<delegate>的优势:
1️⃣具有非常严格的语法格式,所有要响应的事件都必须在协议中进行定义;
2️⃣协议必须在Controller的作用域范围之内进行定义;
3️⃣在一个控制器中可以定义多个不同的协议,但是每个协议的名字不能重复,要确保每个协议的唯一性;
4️⃣如果协议中的一个必须要实现的方法没有实现的话,我们在编译的时候就会出现警告或者是错误;
5️⃣不需要要求第三方的对象必须保持或者是监听整个的通信过程;
6️⃣经常会被用在存在父子关系的对象之间进行通信;
7️⃣可以接收到调用协议方法的返回值;
劣势:
1️⃣需要些很多的代码:
1️⃣.1️⃣协议的定义;
1️⃣.2️⃣控制器中delegate的属性;
1️⃣.3️⃣在协议自身中实现定义协议的方法;
2️⃣我们在释放代理对象的时候,需要将delegate改为nil,如果设定失败的话,调用释放对象的方法将会出现内存方面的异常;
3️⃣经常被用来一对一的通信;
 
通知<Notification>的优势:
1️⃣不需要写太多的代码,实现起来也比较简单;
2️⃣Controller能够传递dictionary对象,在传递的过程中可以携带自定义的信息;
3️⃣可以一对多进行通信(也就是说一个对象发出通知,可以有多个对象做出响应,也可以一对一进行通信);
劣势:
1️⃣我们在对程序进行编译的时候不能检查出发出的通知是否被观察者/监听者做出相应的响应以及正确的进行处理;
2️⃣和delegate对比,通知在发出后,控制器不能从观察者/监听者那里获取到任何的信息;
3️⃣我们在调试应用时很难做到相应的跟踪;
4️⃣在释放注册对象时,需要通过通知中心来取消注册;
5️⃣需要通过第三方的对象来管理控制器与观察者/监听者对象之间的联系;
 
键值监听/键值观察<Key Value Observing>的优势:
1️⃣能够为我们提供被观察对象的属性的最新值以及旧值;
2️⃣通过Key Paths来观察对象的属性;
3️⃣也可以一对多;
4️⃣可以提供一种简单的方法来实现两个对象之间的同步;
5️⃣能够对不是我们手动创建的对象的状态作出响应,同时还不会改变内部对象的实现;
劣势:
1️⃣被我们观察的属性必须要用Strings来定义;
2️⃣当我们释放观察者时不需要移除观察者;
3️⃣如果我们对属性进行重构的话,就会导致我们的观察代码不可用的现象;
 
KVO和Notification的区别:
和delegate的作用一样,KVO和Notification的作用也是用来类与类之间的通信,与delegate不一样的是:
1️⃣这两个都是只负责把通知发出去,至于其他的事情就不管了,因此他们没有返回值;
2️⃣delegate只可以用来进行一对一的通信,而这两个就不一样了,不但可以一对一进行通信,也可以一对多,而且他们都有各自的优势和劣势;
 
从执行的效率来看,当然是delegate比Notification要高。
 
 
以上是个人对三种模式的浅解,希望多提宝贵建议,共同交流和学习哈
posted @ 2016-11-08 11:12  张兆渊  阅读(990)  评论(0编辑  收藏  举报