代理是一种通用的设计模式,在iOS中对代理设计模式支持的很好,有特定的语法来实现代理模式,OC语言可以通过@Protocol实现协议。
代理主要由三部分组成:
-
协议:用来指定代理双方可以做什么,必须做什么。
-
代理:根据指定的协议,完成委托方需要实现的功能。
-
委托:根据指定的协议,指定代理去完成什么功能。
下面是三者的关系图
Protocol-协议的概念
从上图中我们可以看到三方之间的关系,在实际应用中通过协议来规定代理双方的行为,协议中的内容一般都是方法列表,当然也可以定义属性,我会在后续文章中顺带讲一下协议中定义属性。
协议只能定义公用的一套接口,类似于一个约束代理双方的作用。但不能提供具体的实现方法,实现方法需要代理对象去实现。协议可以继承其他协议,并且可以继承多个协议,在iOS中对象是不支持多继承的,而协议可以多继承。
@protocol HomeSearchCellDelegate <NSObject>
-(void)addGoodsCar:(UIButton *)btn;
@end
协议有两个修饰符@optional和@required,创建一个协议如果没有声明,默认是@required状态的。这两个修饰符只是约定代理是否强制需要遵守协议,如果@required状态的方法代理没有遵守,会报一个黄色的警告,只是起一个约束的作用,没有其他功能。
无论是@optional还是@required,在委托方调用代理方法时都需要做一个判断,判断代理是否实现当前方法,否则会导致崩溃。
//判断代理对象是否实现这个方法,没有实现会导致崩溃
if ([_delegaterespondsToSelector:@selector(addGoodsCar:)]) {
[_delegateaddGoodsCar:sender];
}
下面是一个简单的代理列子:
首先定义一个协议类,来定义公共协议,
#import <UIKit/UIKit.h>
@protocol HomeSearchCellDelegate <NSObject>
-(void)addGoodsCar:(UIButton *)btn;
@end
@interface HomeSearchTableViewCell : UITableViewCell{
}
@end
定义委托类,这里做了一个简单的跳转功能,在触发点击方法的时候,把button的信息传递给代理方
#import "HomeSearchTableViewCell.h"
@interface HomeSearchTableViewCell :UITableViewCell{
}
// 通过属性来设置代理对象
@property (weak,nonatomic)id<HomeSearchCellDelegate> delegate;
- (IBAction)addClick:(UIButton *)sender;
@end
@implementation HomeSearchTableViewCell
- (IBAction)addClick:(UIButton *)sender {
//判断代理对象是否实现这个方法,没有实现会导致崩溃
if ([_delegaterespondsToSelector:@selector(addGoodsCar:)]) {
[_delegateaddGoodsCar:sender];
}
}
@end
代理方,实现具体的操作流程,委托方不需要知道实现细节。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
HomeSearchTableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:[HomeSearchTableViewCellgetID]];
if (cell == nil) {
cell= [HomeSearchTableViewCellhomeSearchCell];
cell.delegate=self;
}
return cell;
}
//实现代理以后,再点击cell上btn就会触发这个方法
-(void)addGoodsCar:(UIButton *)btn{
UIView *v = [btn superview];//获取父类view
// UIView *v1 = [v superview];
HomeSearchTableViewCell *cell=(HomeSearchTableViewCell*)[vsuperview];
NSIndexPath *indexPath= [self.tableViewindexPathForCell:cell];//获取cell对应的
这里就会获得点击button 上的具体信息
。。。在这里编写跳转方法。。。
}