ios学习笔记——代理设计模式

在ios项目开发中,我们经常会使用代理设计模式,代理设计模式是一种消息传递的方式,可以通过这种方式来传递一些参数。

代理的基本使用


代理设计模式主要由三部分组成:1、协议,2、代理,3、委托。
1、协议:定义接口,用来指定代理和委托可以做什么,必须做什么。OC语言用@protocol来实现。
2、代理:实现协议接口的方法,完成委托需要实现的任务。
3、委托:根据协议定义deleage对象(代理对象,弱引用weak),指定在什么情况下要求代理对象去完成什么功能。

举个不太恰当的例子:代理模式组成的三部分很像项目经理、需求文档、程序员。需求文档相当于协议,项目经理根据需求文档要求程序员去完成任务。项目经理相当于委托,他根据需求文档,要求程序员去完成需求文档中的任务。程序员相当于代理,根据需求文档,完成项目经理分配的任务。

需求文档(协议)


协议只能定义一套接口,但是不能提供具体的实现。方法需要去实现此协议的类里去实现。

协议可以继承其他协议,并可以继承多个,iOS中不支持多继承,而协议可以,所以iOS中的多继承可以使用协议来代替。

协议有两个修饰符@optional和@required。如果没有声明,默认是@required(必须实现)。这两个修饰符只是约定代理是否强制遵守协议,如果是@required状态的方法没有实现,会报一个黄色的警告,只是起一个约束的作用。

协议通过<>进行实现,一个类可以同时实现多个协议,中间用逗号分隔。

协议中不能定义属性、成员变量等,只能定义方法。

定义协议代码:

1 //声明协议,可以扩展协议
2 @protocol requirementsDocumentDeleage <NSObject>
3 
4 - (void)completeTask;
5 
6 @end

项目经理(委托)


委托类需要显示的声明一个delegate属性,如下

1 //通过属性来实现代理,这里必须用weak,避免引用循环
2 @property (nonatomic, weak) id<requirementsDocumentDeleage> delegate;

这里必须用weak将deleagte声明为弱引用,避免引用循环(不一定造成引用循环,但是这样做比较保险)。

在我们需要deleage做一些事情的时候,我们就需要向delegate发送消息了,代码如下:

1     //判断代理对象存在,是否实现该方法,否则,没有实现会导致崩溃
2     if(self.delegate != nil && [self.delegate respondsToSelector:@selector(completeTask)]){
3         [self.delegate completeTask];
4     }

协议一般声明在委托类的头文件中,如果好多委托类使用协议,则应该单独声明在一个头文件中。

代理对象(程序员)


第一步,这个类必须在声明上,或者类扩展中实现协议,用<>,这里可以实现多个协议,用逗号隔开

1 @interface SJZProgrammerViewController () <requirementsDocumentDeleage>

第二步,设置委托类的delegate对象为代理类对象

1     SJZProjectExperienceView * peView = [[SJZProjectExperienceView alloc] initWithFrame:CGRectMake(0, 200, self.view.frame.size.width, 60)];
2     peView.delegate = self;
3     [self.view addSubview:peView];

第三步,实现协议方法

1 - (void)completeTask
2 {
3     self.label.text = @"完成任务";
4 }

代理实现流程


在ios中代理的本质就是代理对象内存的传递和操作,我们在委托类设置代理对象之后,实际上就是给id类型的指针将代理对象进行了一个弱引用。委托类让代理类执行操作,实际上是在委托类中像这个id类型指针的对象发送消息,而id类型指针指向了代理对象。

代理设计模式的优缺点


优势:

1、语法严格,代理类中所实现的方法必须在协议中有清晰的定义

2、如果代理类中,协议的必须实现方法没有实现那么就会出现编译警告/错误

3、应用中,deleage的控制流程是可跟踪的并且是可识别的

4、可以在一个委托类中定义多个不同的协议,每个协议有不同的delegate

5、没有第三方对象要求保持/监听通信过程

6、委托能够接收调用的协议方法的返回值,这意味着代理类能够反馈信息给委托类

缺点:

1、需要实现的代码比较多:比如协议、delegate属性、协议方法的实现。

2、在释放对象的时候,需要将delegate改为nil,否则,可能在对象释放的时候出现内存泄漏。

3、当多个相同的委托对象的delegate指针指向同一个代理类,这时每个协议方法只能实现一次,处理逻辑比较复杂,需要判断具体是哪个委托对象要求代理类做任务的。

 参考连接:

http://blog.csdn.net/yangxt/article/details/8176636

http://www.cocoachina.com/ios/20160317/15696.html

http://blog.csdn.net/jianxin160/article/details/47753189

原文地址:https://www.cnblogs.com/sjzlovecj/p/5707801.html