在IOS开发中协议和委托是两个密不可分的概念(也可以说是不同的设计模式,只不过在这里我们把他们讲在一起,因为我们常常都是这么用的):确 切来说,协议[protocol]定义了一种规范,使遵循它的类具备一种能力。委托[delegate]则是制定了一种"一个类中需要做的事情交给另一个 类来完成"的途径,通过委托别的类,来调用协议里的方法,委托也可以说是Object-C中实现多继承的一种方式。


委托delegate



在 apple提供的IOS SDK里可以看到很多的delegate,比如我们常用的UITableView,因为我们没有源码,就没有办法知道UITableView里的所谓的 cell是如何增加,删除,复用的。但开发者面对的开发要求使开发者必须具备能够操作这些cell的能力,针对这种情况,各种Delegate就显得非常 重要。



委托delegate是一个简单而强大的设计模式,在此模式中,可以允许一个对象代表另一个对象执行某个操作,或者相互协同操作。



一个很常见的场景就是网络下载数据操作,因为网络数据下载的延迟,一般都会采取多线程的机制,等到数据下载完成之后再通知主线程完成必要的操作。在这个场景中,我们完全可以在主线程实现一个代理方法,在该方法中操作下载好的数据。



协议protocol:



一个完整协议定义如下:



@protocol  协议名



声明方法



@end



其中"声明方法"可以用@required和@optional关键字修饰:



@required 表示我们用到这个协议的时候必须实现这个协议的方法



@optional 表示我们可选择性实现这些方法。



一个类需要遵循的协议在接口声明中的<>填写即可。



示例:






@interface MyViewController : UIViewController //声明继承UIViewController类,遵循UITableViewDataSource和 UITableViewDelegate协议。









@end



那么我们需要在MyViewController类中实现UITableViewDataSource和UITableViewDelegate协议里面的委托方法。



理解协议和委托的关系我们需要搞清楚如下几个问题:



1,一个对象的委托是哪个对象,需要干什么事情;



2,被委托的类需要在自身的interface中声明协议:,表示该来需要实现XXXDelega协议的方法。



3,在被委托的类里定义一个委托类的对象,并设置XXX.dalegate = self。把本类设置成委托对象。然后在本类中实现协议方法。



委托与协议分析示例:



假设公司老板日常的工作是管理公司、起草文件和接电话。



其中管理公司是老板要亲自做的。而起草文件与接电话老板希望秘书来帮忙,于是对秘书的要求就是要懂得文字编辑,要能帮助领导接电话。而这两项要求便是协议。



  1. //制定协议  
  2. //protocol.h 
  3. #import  
  4. @protocol tekuba_net   
  5. //起草文件 
  6. -(void)draftDocuments;  
  7. //接电话 
  8. -(void)tel;  
  9. @end  
  10.  
  11. //秘书类 
  12. // Sec.h 
  13. #import  
  14. #import "protocol.h" 
  15. @interface Sec : NSObject  
  16. @end  
  17. //Sec.m 
  18. #import "Sec.h" 
  19. @implementation Sec  
  20. - (id)init  
  21. {  
  22.    self = [super init];  
  23.    if(self) {  
  24.    // Initialization code here. 
  25.    }  
  26.    returnself;  
  27. }  
  28. -(void)draftDocuments  
  29. {  
  30.    NSLog(@"sec draft documents");  
  31. }  
  32. -(void)tel  
  33. {  
  34.    NSLog(@"sec tel");  
  35. }  
  36. @end  
  37. //老板类 
  38. // Boss.h 
  39. #import  
  40. #import "protocol.h" 
  41. @interface Boss : NSObject  
  42. //很重要的属性-此属性对象必须实现protocol协议。在实际使用过程中常常用self.delegate = XXX. 
  43. @property(nonatomic,retain) id detegate; //必须有一个protocol类的对象,在实际使用过程中需要配置这里的delegate指向代理对象。 
  44. //管理公司 
  45. -(void)manage;  
  46. @end  
  47. // Boss.m 
  48. #import "Boss.h" 
  49. @implementation Boss  
  50. @synthesize detegate=_detegate;  
  51. -(id)init  
  52. {  
  53.    self = [super init];  
  54.    if(self) {  
  55.    // Initialization code here. 
  56.    }  
  57.    returnself;  
  58. }  
  59. -(void)manage  
  60. {  
  61.    NSLog(@"boss manage");  
  62. }  
  63. -(void)draftDocuments  
  64. {  
  65.    NSAutoreleasePool *p=[[NSAutoreleasePool alloc] init];  
  66.    [_detegate draftDocuments];  
  67.    [p release];  
  68. }  
  69. -(void)tel  
  70. {  
  71.    NSAutoreleasePool *p=[[NSAutoreleasePool alloc] init];  
  72.    [_detegate tel];  
  73.    [p release];  
  74. }  
  75. @end  



那么老板就具有这3个方法,当调用前1个时是自己完成功能,而调用后2个时则转为委托调用秘书的方法。



测试用例如下:

1. main.m  
2. #import  
3. #import "Boss.h" 
4. #import "Sec.h" 
5. intmain (intargc, constchar* argv[])  
6. {  
7.    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
8.    //实例化老板对象 
9.    Boss *boss=[[[Boss alloc] init] autorelease];  
10.    //实例化秘书对象 
11.    Sec *sec=[[[Sec alloc] init] autorelease];  
12.    //设置老板的代理对象为秘书 
13.    boss.detegate=sec;//关键代码   
14.    //调用各个方法。 
15.    [boss draftDocuments];  
16.    [boss tel];  
17.    [boss manage];  
18.    [pool drain];  
19.    return0;  
20. }