活得快乐的最重要因素是人生有事干、有人可去爱,以及生命中有所冀望。
协议
一. 协议基本概念
1. 协议的理解
iOS里面协议不是类,它是一种约定。协议约定了一套行为规范,并且约定了那些是必须要遵守的规范,那些是可准守可不遵守的规范。但是具有的实施(也就是实现),是由遵循该协议的类来实现,所以协议只有.h文件。
基于以上概念我们应该明白对于协议的理解,以前很多的开发者依旧保留在委托-代理
等于协议
等认知上。然而前者依赖于后者的实现,而后者即便不通过前者也能完成抽象解耦的工作。
2. 协议的定义形式
协议的定义是以@protocol
开头, + 协议的名字 <>(表示服从的协议),服从的协议写在<>之内,多个协议之间通过逗号来进行分隔,父协议中的内容就相当于子协议也具有这些内容,以@end结束。
@protocol CustomProtocol <NSObject>
// 声明相关方法,也就是协议内容
- (void)customProtocolMethod;
@end
二. 协议的应用
1. 委托-代理模式中的应用
开发中我们几乎都会写的代码一定是UITableView
系列的代理和数据源方法。毫无疑问,苹果提供的这个视图是如此的优雅而强大,即便在现在这个数据源方法因代码过多被疯狂吐槽的年代,你依然无法想到其他实现UITableView
的更佳实践,这个控件充分向我们展示了委托-代理
的强大。
协议最简单直观的应用是在委托-代理
设计模式中的应用,在封装自定义控件的时候,我喜欢使用自定义的协议来完成用户点击等业务处理。个人认为,如果你想要了解代理
这一模式,起码要自定义过自己的代理协议:
// 定义相关协议
@protocol CustomViewDelegate <NSObject>
@required
- (void)customControl: (UIView *)customView didSelectItemAtIndex: (NSUInteger)index;
@end
// .h文件
@interface CustomView : UIView
// 通过属性来设置代理对象
@property(nonatomic, weak)id<CustomViewDelegate> delegate;
@end
// .m文件
@implementation CustomView
- (void)clickItem: (UIButton *)item
{
// 判断代理对象是否实现了某个协议方法
if ([_delegate respondsToSelector:@selector(customControl:didSelectItemAtIndex:)]) {
[_delegate customControl:self didSelectItemAtIndex:item.tag];
}
}
@end
// 代理类此处省略...
// 我们可以通过以下方法判断该对象是否引入相关协议
if([_delegate conformToProtocol:@protocol (CustomViewDelegate)]){
//TODO:
}
对于项目开发而言,代理这种回调机制的好处包括不仅于接口目的性强、易于追溯调试等。
三. 委托-代理
1. 委托代理的理解
上面我们提到过委托-代理的使用,那么接下来我们详细理解下委托-代理。
代理,又称委托代理(delegate),是iOS中常用的设计一种模式。顾名思义,它是把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代替它来打理要做的事。反映到程序中, 首先要明确一个对象的委托方是哪个对象,委托所做的内容是什么。在iOS程序设计中,委托通过一种@protocol的方式实现,所以又称为协议。在iOS的SDK里面,UITableView、UITextField等都有用到这种设计模式。
协议,是多个类共享的一个方法列表,在协议中所列出的方法没有响应的实现,由其它类来实现。委托是指给一个对象提供机会对另一对象中的变化做出反应或者相应另一个对象的行为。其基本思想是协同解决问题。
代理是一个概念,很难用一个名词去定义(如我们可以说协议其实就是一个方法列表)。它更像是一种关系,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事。这个时候,这位其他人就是我的代理。
2. 委托代理的应用
委托代理主要应用于对象之间的通信,是一种通信机制。具体应用于以下几个经典案例:
- 页面跳转过程中数据的回调,比如页面A -> B,B -> 过程中数据的回调;
- 处理事件响应,控制器中添加自定义视图的时候,一般点击自定义视图触发的事件,需要委托控制器响应处理,这个时候用委托代理设计模式是一个比较好的选择之一;
- 控制器瘦身,例如我们经常用到的控制器
UITableView
,我们将UITableView
的delegate
和DataSource
单独拿出来,由一个代理对象类进行控制,只将必须控制器处理的逻辑传递给控制器处理。UITableView
的数据处理、展示逻辑和简单的逻辑交互都由代理对象去处理,和控制器相关的逻辑处理传递出来,交由控制器来处理,这样控制器的工作少了很多,而且耦合度也大大降低了。这样一来,我们只需要将需要处理的工作交由代理对象处理,并传入一些参数即可。
委托-代理优秀博客推荐:https://segmentfault.com/a/1190000019569138