iOS设计模式之代理模式(一)
在项目中经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式传递一些参数。在项目中,刚开始我是用一些代理来传递参数的,但是慢慢觉得代理的代码比较block多,所以就更多的使用了block。前几天突然想到了代理的设计模式,回头又详细看了下代理的相关文档,在此把个人看法记录下来。
目录
基本概念
苹果官方文档对代理设计模式作了精练的描述:
“代理设计模式是一种简单却又强大的设计模式。在这个模式中,一个对象可以与另一对象进行协同交互,或者直接代表另一对象行动。委托对象(the delegating object)中会保有一个指向代理对象(the delegate)的引用,并在合适的时机向他发送消息,通知他委托对象即将或已经处理完毕的事件。代理对象收到通知后,可以通过更新自己或其他对象的展现形式(UI界面)或状态来进行响应,在某些情况下也可以返回一个值给委托对象以影响其对即将发生的事件的处理。代理设计模式的主要价值在于可以让人在一个主对象中轻松定制各种对象的行为。”
protocol–协议
协议是公共的定义,如果只是某个类使用,我们常做的就是写在某个类中。如果是多个类都是用同一个协议,建议创建一个Protocol文件,在这个文件中定义协议。遵循的协议可以被继承,例如我们常用的UITableView,由于继承自UIScrollView的缘故,所以也将UIScrollViewDelegate继承了过来,我们可以通过代理方法获取UITableView偏移量等状态参数。
协议可以继承其他协议,并且可以继承多个协议,在iOS中对象是不支持多继承的,但是协议可以.
代理对象
代理对象在很多情况下其实是可以复用的,可以创建多个代理对象为对个委托方服务.
怎样写一个代理设计模式
- 你要明确你的协议名称,一般来讲名称都是:控件类名 + Delegate
- 代理方法中一般都是声明为@optional(程序默认情况下是@required)
- 代理方法名一般以控件开头
- 代理方法至少有一个参数
举个例子
假如你喜欢一个女生,你想送礼物给她,但是你又不认识人家,这时候恰巧你的同学A认识这个女同学,这时候你(委托也叫代理对象)请求你的同学A(代理也叫委托对象)代你送礼物给这个女生。
那这个送一些什么礼物就是你和你同学A协商的协议。文末有我在GitHub上的Demo。感兴趣的可以去看看。
代理内存管理
delegate的属性都是用weak,因为strong类型的指针会造成强引用,必定会影响一个对象的生命周期,这也就会形成循环引用.
代理和block的选择
• 从设计模式的角度来说,代理更佳面向过程,而block更佳面向结果。
• 从性能上来说,block的性能消耗要略大于delegate,因为block会涉及到栈区向堆区拷贝等操作,时间和空间上的消耗都大于代理。而代理只是定义了一个方法列表,在遵守协议对象的objc_protocol_list中添加一个节点,在运行时向遵守协议的对象发送消息即可。
• 有多个相关方法。假如每个方法都设置一个 block, 这样会更麻烦。而 delegate 让多个方法分成一组,只需要设置一次,就可以多次回调。当多于 3 个方法时就应该优先采用 delegate。
• 为了避免循环引用,也可以使用 delegate。
模式总结
• 具有良好的扩展性。委托的业务逻辑可能会随时改变,当有新增功能,只需要在协议中增加方法就能不影响原有功能的情况下增加新功能
• 有利于代码的封装。如果一个类,实现了某个协议,那么这个协议中的属性或方法就不必公有化,就可以被定义协议的类调用。这样可以减少一个类暴露给外部的方法
• 有利于程序的结构化与层次化。一个协议往往是解决某一个问题,对于一个其他的不过却类似的问题,我们只用再次实现协议即可,避免了自己再次构思一组方法,提高代码的复用性
感兴趣可以看我的github上的代理模式demo