一、什么是代理模式
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作
简单来说就是: 为其他对象提供一种代理,控制对该对象的访问
代理主要由三部分组成
- 协议 指定双方能实现什么和必须要实现什么
- 代理 根据指定的协议 实现委托方需要的功能
- 委托 根据协议,指定代理去完成什么
例如我们最常见的UITableView
,他的常用代理为UITableViewDelegate
,UITableViewDataSource
,当我们定义一个列表的时候,我们需要引入这两个协议,同时遵循delegate
和dataSource
代理,然后实现协议中为我们提供的方法就可以了, 外部使用方并不需要知道这些方法具体是怎么实现的.
协议有两种修饰符@optional
和@required
,当修饰符为@required
时,则下面的协议方法必须要实现.
在委托方调用方法时,需要判断代理是否实现当前方法,否则会崩溃
二、应用场景
消息传递
A想要干某事 委托B去干
三、如何使用
定义协议
@protocol DNLoginViewDelegate <NSObject>
@required
- (void)loginBtnClickWithUsername:(NSString *)username password:(NSString *)password;
@end
定义委托类
@interface DNLoginView : UIView
@property (nonatomic, weak) id <DNLoginViewDelegate>delegate;
@end
@implementation DNLoginView
- (void)loginBtnClick:(UIButton *)sender {
if (self.delegate && [self.delegate respondsToSelector:@selector(loginBtnClickWithUsername:password:)]) {
[self.delegate loginBtnClickWithUsername:self.usernameTextField.text password:self.passwordTextField.text];
}
}
@end
实现代理
@interface DNLoginViewController () <DNLoginViewDelegate>
@property (nonatomic, strong) DNLoginView *loginView;
@end
@implementation DNLoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.navigationItem.title = @"登陆";
[self.view addSubview:self.loginView];
}
#pragma mark - DNLoginViewDelegate
- (void)loginBtnClickWithUsername:(NSString *)username password:(NSString *)password {
NSLog(@"loginBtnClick username: %@, password: %@", username, password);
}
- (DNLoginView *)loginView {
if (!_loginView) {
_loginView = [[DNLoginView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 200)];
_loginView.delegate = self;
}
return _loginView;
}
四、总结
优点
- 代理方和委托方不需要了解对方的具体方法,实现解耦
- 职责清晰
- 扩展性高
缺点
- 一对一,需要签订协议