delegate(代理)
- delegate是一种设计模式,在OC中应用非常广泛。可将delegate看着一个对象,「它专门代表被代理对象来和程序中其他对象打交道的。」
- Cocoa Touch框架的每个UI控件类里面都声明了一个类型为id的delegate或是dataSource,查看Cocoa的头文件可以发现很多如下的属性:
@property(nonatomic, assign)id<UIActionSheetDelegate> delegate; // weak reference
通常格式为
@property(nonatomic, assign)id<protocol_name> delegate;
即这个代理要遵循某一个协议,也就是说只有遵循了这个协议的类对象才具备代理资格。这同时也要求了代理类必须在头文件中声明遵循这个protocol_name协议并实现其中的@required方法,@optional的方法是可选的。
protocol(协议)
- 相当于C++中的纯虚函数,是一个方法申明列表,但不负责实现。protocol可用于代理传值和定义接口。另外,它定义的方法列表有以下两个类型:
- @required:必须实现此方法(遵守此协议的对象)
- @optional:可以不实现此方法(遵守此协议的对象)
- 假如对象遵守了protocol的话,也必须实现protocol中的方法(@required),就是在定义类的头文件中使用<> 将所需要的协议引入,如果引入多个协议,用”,”分隔,譬如:
@interface MyClassView:UIViewController <MyDelegate, UIAlertViewDelegate> //TODO: balabalabala... @end
- 相当于C++中的纯虚函数,是一个方法申明列表,但不负责实现。protocol可用于代理传值和定义接口。另外,它定义的方法列表有以下两个类型:
delegate和protocol关系
Cocoa Touch中大量使用了这两种设计模式:- 首先用protocol定义一个方法列表
- 在代理对象中定义一个遵守此协议的公开属性
- 在被代理对象的头文件中使用<> 将所需要的协议引入
- 配置代理关系(将被代理对象赋予第2步申明的属性)
- 实现协的方法
- 在代理对象中适当的地方,调用被代理对象中实现的协议方法。
一个例子:
代理对象
//.h
//定义方法列表
@protocol TrackPlaybackDelegate <NSObject>
//@required //强制方法列表
@optional //可选方法列表
-(void)didDealloc;
@end
//定义公开属性
@interface TrackPlaybackViewController
//实现了TrackPlaybackDelegate协议的对象才能有资格成为delegate
@property(nonatomic,weak) id<TrackPlaybackDelegate> delegate;
@end
//.m
//在适当的地方调用被代理对象的方法
...
//绑定了didDealloc方法的对象,才向它发送消息(即调用方法).
if (self.delegate && [self.delegate respondsToSelector:@selector(didDealloc)]) {
[self.delegate performSelector:@selector(didDealloc)];
//或带参数1个用[self.delegate performSelector:<#(SEL)#> withObject:<#(id)#>];
//或带参数2个用[self.delegate performSelector:<#(SEL)#> withObject:<#(id)#> withObject:<#(id)#>];
}
...
被代理对象
//.h
//引入协议
@interface TrackViewController <TrackPlaybackDelegate>
//.m
...
__weak typeof(&*self) weakSelf = self; //可选,如果delegate定义的是强引用,这样可避免self被ratin无法释放.
TrackPlaybackViewController *PlaybackVC = [[TrackPlaybackViewController alloc]init];
PlaybackVC.delegate = (id)weakSelf; //配置代理关系
...
//实现协议方法
-(void)didDealloc{
//do something...;
}