目录
第四章:协议与分类
协议(protocol)和分类(category)是OC的两个重要的语言特性。理解并运用得当,可令代码易读、易维护且少出错。
第23条:通过委托与数据源协议进行对象间通信
可以通过委托(代理 delegate)与数据源(data source)协议进行对象间通信。
协议中可以定义方法和属性。
在协议中@optional
和@require
关键字来指定协议方法是可选择实现的还是必须实现的,如果适用方没有实现@require方法那么编译器就会给出警告。
委托模式
何为代理?一种软件设计模式,iOS中@protocol
形式体现,传递方式为一对一。
代理模式的主旨:定义一个委托协议,若对象想接受另一个对象(委托方)的委托,则需遵守该协议,以成为 “代理方”。而委托方则可以通过协议方法给代理方回传一些信息,也可以在发生相关事件时通知代理方。这样委托方就可以把应对某个行为的责任委托给代理方去处理了。
代理的工作流程:
委托方要求代理方把需要实现的方法全都定义在委托协议中;
代理方遵循协议并实现协议中的方法(若有返回值会返回给委托方);
委托方调用代理方遵从的协议方法。
delegate
属性一般定义为weak以避免循环引用,代理方强引用委托方,委托方弱引用代理方。
如果要向外界公布一个类遵守某协议,那么就在接口中声明;如果这个协议是委托协议,那么就在类扩展中声明,因为该协议通常只会在类的内部使用。
对于@optional
方法,在委托方法中调用时,需要先判断代理方是否能响应(是否实现了该方法),如果能响应才能给它发送协议消息,否则代理方可能没有实现该方法,调用时就会因找不到方法实现而导致Crash:
//最好先判断一下delegate是否存在提高执行效率
if (_delegate && [_delegate respondsToSelector:@selector(protocolOptionalMethod)]) {
[_delegate protocolOptionalMethod];
}
数据源模式
委托模式的另一用法,旨在向类提供数据,所以也称“数据源模式”,其用协议定义一套接口,令某类经由该接口获取所需的数据。
在此模式中,信息从数据源流向委托方;
在常规模式中,信息从类(委托方)流向代理方(受委托方)。
通过UITableView就可以很好的理解Data Source和Delegate这两种模式:
-
通过UITableViewDataSource协议获取要在列表中显示的数据;
-
通过UITableViewDelegate协议来处理用户与列表的交互操作。
@protocol UITableViewDataSource <NSObject> @required - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; @optional - (NSInteger)numberOfSectionsInTableView: