代理是一种简单而功能强大的设计模式,这种模式用于一个对象“代表”另一个对象和程序中其他的对象进行交互。
主对象中维护一个代理(delegate)的引用并且在合适的时候向这个代理发送消息。这个消息通知“代理”主对象即将处理或是已经处理完了某一件事。
这个代理可以通过自己或是其他对象的UI界面或是其他专题来响应主对象所发送过来的这个事件的消息。或是在某些情况下能返回一个值来影响其他即将发生的事件该如何来处理。
代理的主要价值是它可以让你容易的定制各种对象的行为。注意这里的代理是一个名词,它本身是一个对象,这个对象是专门代表被代理对象来和程序中其他对象打交道的。
代理设计模式是软件编程中进行数据传递的一种重要方式,这种模式十分抽象,但在UIKit框架中却随处可见。
举一个例子来说,古时候,盲人背着一个瘸子走路,瘸子看到前面有一个水坑,他告诉盲人让他绕过去,盲人听从瘸子的只会,两个人平安到达目的地。
在这一组行为中,瘸子看到前面的障碍,可是瘸子不能走路;另一方面,盲人可以走路,但是他看不到,他不知道这个障碍是否存在。于是,语言的沟通就充当了瘸子和盲人之间的代理,瘸子看到障碍后通过语言沟通将这个信息高速盲人,盲人获取信息,绕过障碍。
类比编程开发中,系统UI控件充当着故事中的瘸子的角色,开发者充当着盲人的角色,当系统UI控件接收到用户的一些动作行为时它并不知道该怎么处理这些行为逻辑,于是通过代理方法将用户的这一动作告诉开发者,开发者在代理方法中处理相关的程序逻辑。
例如:食品公司和面粉供应商之间
1.制定一个协议(新建一个Food类)
.h文件
#import <UIKit/UIKit.h>
//制定一个协议
//协议名称一般是类名+Delegate
@protocol FoodDelegate <NSObject>
//定义一个方法
-(void)needFlour;
@end
@interface Food : UIView
//制定完协议之后,定义一个属性
@property (nonatomic,weak)id<FoodDelegate>food;
@end
.m文件
#import "Food.h"
@implementation Food
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
//实例化一个button
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
//为button设置背景颜色
[button setBackgroundColor:[UIColor redColor]];
//添加监听方法
[button addTarget:self
action:@selector(clickButton) forControlEvents:UIControlEventTouchUpInside];
//添加button
[self addSubview:button];
}
return self;
}
//监听方法
-(void)clickButton{
//点击的时候说明缺原料了
NSLog(@"原料短缺,赶紧配送");
#warning 调用代理方法
//respondsToSelector:返回一个BOOL值,如果该对象实现了这个方法,就返回yes,如果没有就返回no
//使用这种方法,在viewController.m中即使不实现代理方法也不会崩溃
if ([self.food respondsToSelector:@selector(needFlour)]) {
//通知代理调用代理方法
[self.food needFlour];
}
}
@end
ViewController.m文件
#import "ViewController.h"
#import "Food.h"
//首先遵守协议
@interface ViewController ()<FoodDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Food *foodView = [[Food alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
//设置颜色
[foodView setBackgroundColor:[UIColor orangeColor]];
//设置代理
foodView.food = self;
//添加view
[self.view addSubview:foodView];
}
#pragma mark-
#pragma mark- 实现代理方法
-(void)needFlour{
NSLog(@"面粉来了");
}
@end