代理模式

在iOS中代理的本质就是代理对象内存的传递和操作,我们在委托类设置代理对象后,实际上只是用一个id类型的指针将代理对象进行了一个弱引用。委托方让代理方执行操作,实际上是在委托类中向这个id类型指针指向的对象发送消息,而这个id类型指针指向的对象,就是代理对象。
 
在iOS2.0之前还没有引入@Protocol正式协议之前,实现协议的功能主要是通过给NSObject添加Category的方式。这种通过Category的方式,相对于iOS2.0之后引入的@Protocol,就叫做非正式协议。
非正式协议中没有@Protocol的@optional和@required之分,和@Protocol一样在调用的时候,需要进行判断方法是否实现。
 
  • 多个消息传递,应该使用delegate。

  • 在有多个消息传递时,用delegate实现更合适,看起来也更清晰。block就不太好了,这个时候block反而不便于维护,而且看起来非常臃肿,很别扭。

  • 例如UIKit的UITableView中有很多代理如果都换成block实现,我们脑海里想一下这个场景,这里就不用代码写例子了…..那简直看起来不能忍受。

  • 一个委托对象的代理属性只能有一个代理对象,如果想要委托对象回调多个代理对象应该用block。(这里主要是针对于对象内部属性不会对block进行引用的情况下,否则再调用同一个方法也会造成重新赋值问题)
 
如果设置多个代理相当于重新赋值,只有最后一个设置的代理才会被真正赋值。

单例对象最好不要用delegate。

但是我们还是需要注意一点,在多线程情况下因为是单例对象,我们对block中必要的地方加锁,防止资源抢夺的问题发生。
 
从设计模式的角度来说,代理更佳面向过程,而block更佳面向结果。
 
从性能上来说,block的性能消耗要略大于delegate,因为block会涉及到栈区向堆区拷贝等操作,时间和空间上的消耗都大于代理。而代理只是定义了一个方法列表,在遵守协议对象的objc_protocol_list中添加一个节点,在运行时向遵守协议的对象发送消息即可。
 
delegate属性之所以用weak修饰是为了避免循环引用.
如果一个对象为另一个的代理,另一个的代理属性为strong,二者即为循环应用.
原文地址:https://www.cnblogs.com/fangweiyi/p/5548369.html