代理,又称委托代理(delegate),是iOS中常用的设计一种模式。顾名思义,它是把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代替它来打理要做的事。反映到程序中, 首先要明确一个对象的委托方是哪个对象,委托所做的内容是什么。在iOS程序设计中,委托通过一种@protocol的方式实现,所以又称为协议。在iOS的SDK里面,UITableView、UITextField等都有用到这种设计模式。
协议,是多个类共享的一个方法列表,在协议中所列出的方法没有响应的实现,由其它类来实现。委托是指给一个对象提供机会对另一对象中的变化做出反应或者相应另一个对象的行为。其基本思想是协同解决问题。
从方法的定义我们不难看出委托模式能够起到两方面的作用:
第一:代理协助对象主体完成某项操作,将需要定制化的操作通过代理来自定义实现,达到和子类化对象主体同样的作用。第二:事件监听,代理对象监听对象主体的某些重要事件,对事件做出具体响应或广播事件交给需要作出响应的对象。
个人理解采用委托模式的好处在于:1、避免子类化带来的过多的子类以及子类与父类的耦合2、通过委托传递消息机制实现分层解耦
在程序中:一般情况下
1.委托需要做的工作有:
1.1定义协议与方法
1.2声明委托变量
1.3设置代理
1.4通过委托变量调用委托方法
2.代理需要做的工作有:
2.1遵循协议
2.2实现委托方法
比如,学生想要买一本专业书,书店没有这本书,自己又不直接去出版社,于是,学生就委托书店,帮忙买书,书店就是学生的代理。
学生 Student.h里面:
#import <Foundation/Foundation.h> //定义协议与方法 @protocol StudentBuyBookDelegate<NSObject> -(void)buyBook:(NSString *)name price:(int)p; @end @interface Student : NSObject //声明委托变量 @property(nonatomic,retain)id<StudentBuyBookDelegate> stu_delegate; -(void)wantBuy; @end学生 Student.m里面:
#import "Student.h" @implementation Student -(void)wantBuy { NSLog(@"学生:我想买IOS开发的书"); //通过委托变量调用委托方法 [self.stu_delegate buyBook:@"IOS开发" price:50]; } @end
书店BookShop.h
#import <Foundation/Foundation.h> #import "Student.h" //书店遵守StudentBuyBookDelegate的委托协议 @interface BookShop : NSObject<StudentBuyBookDelegate> @end
书店 BookShop.m
#import "BookShop.h" @implementation BookShop //书店实现协议的方法 -(void)buyBook:(NSString *)name price:(int)p { NSLog(@"我可以以%i元的价格把%@卖个你",p,name); } @end
在ViewController.m里面
Student *student =[[Student alloc]init]; BookShop *bookshop = [[BookShop alloc]init]; //学生设置代理,委托书店买书 student.stu_delegate=bookshop; //判断书店是否实现了协议,避免未实现带来的崩溃 if ([bookshop respondsToSelector:@selector(buyBook:price:)]) { [student wantBuy]; }
结果如图:
总结:协议是一个方法签名的列表,在其中可以定义若干个方法。根据配置,遵守该协议的类会去实现这个协议中规定的若干个方法。代理是一个概念,很难用一个名词去定义(如我们可以说协议其实就是一个方法列表)。它更像是一种关系,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事。这个时候,这位其他人就是我的代理。
本文侧重于概念的理解,通过学生书店购书的例子,解释了代理协议的概念。下文《iOS 用代理实现界面反向传值》将侧重于代理协议在iOS 程序设计的应用,比如界面反向传值等等。