为什么使用委托?
答:比如,我上班的工作主要内容包括 (1)写代码(2)写文档(3)测试程序(4)接电话(5)会见客户
(1)(2)我自己全权负责,但是后面(3)(4)(5)我不想或者不方便自己做,所以我想找个助手(delegate)帮我做这些事,于是我定了一个招聘要求(Protocol),里写明我的助手需要会做(3)(4)(5)这三件事。很快,我招到一个助手。
我.delegate = 助手;
于是以后每当我遇到需要测试程序或者接电话的活,我就把他转交给助手(delegate)去处理,助手处理完后如果有处理结果(返回值)助手会告诉我,也许我会拿来用。如果不需要或者没有结果,我就接着做下面的事。
1 协议(Protocol)
协议限制了实现类必须拥有哪些方法。它是对对象行为的定义,也是对功能的规范。
示例:
// GoodChild.h #import <Foundation/Foundation.h> @protocol GoodChild <NSObject> -(void)filialPiety; //孝顺 @end
// Student.h #import <Foundation/Foundation.h> #import "GoodChild.h" //注意实现协议的语法。 @interface Student : NSObject<GoodChild> @end // Student.m #import "Student.h" @implementation Student - (id)init { self = [super init]; if (self) { // Initialization code here.} return self; } -(void)filialPiety{ NSLog(@"孝敬父母。。");} @end
此例中定义了一个协议GoodChild,类Student实现了此协议,所以必须有filialPiety方法。每个类虽只有一个父类,但可以实现多个协议,以逗号隔开便可。语法如下:
@interface Student : NSObject<协议1,协议2> @end
2.委托(Delegate)
委托是objC中使用非常频繁的一种设计模式,它的实现与协议的使用是分不开的。
让我们看一个综合示例:小公司老板日常的工作是管理公司、教导新员工、发工资与接电话。其中管理公司、教导新员工是老板要亲为的。而发工资与接电话老板希望招聘一个秘书来帮忙,于是对秘书的要求就是要略懂出纳发工资,要能帮助领导接电话。而这两项要求便是协议,对类功能的限定。
// SecProtocol.h #import <Foundation/Foundation.h> @protocol SecProtocol <NSObject> //发工资 -(void)payoff; //接电话 -(void)tel; @end
然后定义一个秘书类:
// Sec.h #import <Foundation/Foundation.h> #import "SecProtocol.h" @interface Sec : NSObject<SecProtocol> @end // Sec.m #import "Sec.h" @implementation Sec - (id)init { self = [super init]; if (self) { // Initialization code here. } return self; } -(void)payoff{ NSLog(@"sec payoff"); } -(void)tel{ NSLog(@"sec tel"); } @end
紧接着是老板类:
// Boss.h #import <Foundation/Foundation.h> #import "SecProtocol.h" @interface Boss : NSObject
//此属性用于指定秘书对象,此对象必须实现SecProtocol协议。 @property(nonatomic,retain) id<SecProtocol> detegate; //管理 -(void)manage; //教导新员工 -(void)teach; @end // Boss.m #import "Boss.h" @implementation Boss @synthesize detegate=_detegate; - (id)init {
self = [super init]; if (self) { // Initialization code here.} return self; } -(void)manage{ NSLog(@"boss manage"); } -(void)teach{ NSLog(@"boss teach"); } -(void)payoff{ NSAutoreleasePool *p=[[NSAutoreleasePool alloc] init]; [_detegate payoff]; [p release]; } -(void)tel{ NSAutoreleasePool *p=[[NSAutoreleasePool alloc] init]; [_detegate tel];
[p release]; } @end
那么老板就具有这4个方法,当调用前2个时是自己完成功能,而调用后2个时则转为调用秘书的方法。此时我们跟秘书对象就叫做代理对象,代理模式的名字由来于此。最后调用测试下:
// main.m #import <Foundation/Foundation.h> #import "Boss.h" #import "Sec.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //实例化老板对象 Boss *boss=[[[Boss alloc] init] autorelease]; //实例化秘书对象 Sec *sec=[[[Sec alloc] init] autorelease]; //设置老板的代理对象为秘书 boss.detegate=sec; //调用4个方法。 [boss payoff]; [boss tel]; [boss manage]; [boss teach]; [pool drain]; return 0; }