Objective-C中的委托

引用:http://blog.csdn.net/tianyitianyi1/article/details/7681226

委托在IOS开发框架Cocoa Touch 中经常使用,其含义是一个类的对象要求委托对象执行它的某些操作。委托机制实际是种设计模式,通过此种机制,能降低对象间的耦合。还是不继续说概念了,直接上定义代码(点这里下载)

//环境

//Mac OS X 10.3.7

//Xcode Version 4.2.1

//使用的是Xcode的Command Line Tool工程,结果由命令行输出

[cpp]  view plain copy
  1. @interface MyFrameWork : NSObject{  
  2. }  
  3. @property (nonatomic,assign)NSObject * delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类   
  4. - (id)init;  
  5. - (void) callDelegate;  
  6. @end  
[cpp]  view plain copy
  1. @interface MyFrameWork : NSObject{  
  2. }  
  3. @property (nonatomic,assign)NSObject * delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类  
  4. - (id)init;  
  5. - (void) callDelegate;  
  6. @end@interface MyFrameWork : NSObject{  
  7. }  
  8. @property (nonatomic,assign)NSObject * delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类  
  9. - (id)init;  
  10. - (void) callDelegate;  
  11. @end  
[cpp]  view plain copy
  1. #import "MyFrameWork.h"   
  2.   
  3. @implementation MyFrameWork  
  4. @synthesize delegate;  
  5.   
  6. - (NSString *) description{  
  7.     return (@"I am MyFrameWork");  
  8. }  
  9. -(id) init{  
  10.     self = [super init];  
  11.     if (self){  
  12.    
  13.     }  
  14.     return  self;      
  15. }  
  16. <pre name="code" class="cpp">-(void)callDelegate{  
  17.     //通过delegate指针访问类Delegate的description方法   
  18.     NSString *string = [self.delegate description];  
  19.     //发现在最新版的编译器里面NSLog为了安全(支持ARC),只接受格式化的字符串,因为NSLog底层也是用printf来格式化输出的。   
  20.     //NSLog(str);                          // warning   
  21.     // NSLog(@"%@", str);         // solution   
  22.     // NSLog(str, nil);                   // solution   
  23.     NSLog(string,nil);  
  24.   
  25. }  
[cpp]  view plain copy
  1. #import "MyFrameWork.h"  
  2.   
  3. @implementation MyFrameWork  
  4. @synthesize delegate;  
  5.   
  6. - (NSString *) description{  
  7.     return (@"I am MyFrameWork");  
  8. }  
  9. -(id) init{  
  10.     self = [super init];  
  11.     if (self){  
  12.    
  13.     }  
  14.     return  self;      
  15. }  
  16. <pre name="code" class="cpp">-(void)callDelegate{  
  17.     //通过delegate指针访问类Delegate的description方法  
  18.     NSString *string = [self.delegate description];  
  19.     //发现在最新版的编译器里面NSLog为了安全(支持ARC),只接受格式化的字符串,因为NSLog底层也是用printf来格式化输出的。  
  20.     //NSLog(str);                          // warning  
  21.     // NSLog(@"%@", str);         // solution  
  22.     // NSLog(str, nil);                   // solution  
  23.     NSLog(string,nil);  
  24.   
  25. }  
 
[cpp]  view plain copy
  1. @interface Delegate : NSObject  
  2. @property NSInteger number;  
  3. -(id)init;  
  4. @end  
[cpp]  view plain copy
  1. @interface Delegate : NSObject  
  2. @property NSInteger number;  
  3. -(id)init;  
  4. @end  
[cpp]  view plain copy
  1. #import "Delegate.h"   
  2. @implementation Delegate  
  3. @synthesize number;  
  4. -(NSString *)description{  
  5.     self.number = self.number + 1;  
  6.     NSString *string = [[NSString alloc] initWithFormat:@"I am Delegate,%ld calls",self.number];  
  7.     return (string);  
  8. }  
  9. -(id)init{  
  10.     self = [super self ];  
  11.     if (self) {  
  12.         self.number =0;  
  13.     }  
  14.     return self;  
  15. }  
  16. @end  
[cpp]  view plain copy
  1. #import "Delegate.h"  
  2. @implementation Delegate  
  3. @synthesize number;  
  4. -(NSString *)description{  
  5.     self.number = self.number + 1;  
  6.     NSString *string = [[NSString alloc] initWithFormat:@"I am Delegate,%ld calls",self.number];  
  7.     return (string);  
  8. }  
  9. -(id)init{  
  10.     self = [super self ];  
  11.     if (self) {  
  12.         self.number =0;  
  13.     }  
  14.     return self;  
  15. }  
  16. @end  
       首先定义了两个类,MyFrameWork类通过Delegate类完成访问Delegate的description方法。很简单便完成了委托,这也跟objective-c面向对象和灵活的特点相稳合,如果熟悉C++的童鞋,就会发现上述同样的功能的比较难完成,C++没有共同的父类,所以不存在一个指针可以指向任意的委托对象,这似乎是个不可解决的问题。但C++中有类的成员函数指针这一概念,具体的实现可以看一下 这篇博文(点击) ,多参数时实现的很巧妙。总之objective-c委托实现很简单(大家不许偷笑),但很少会像上面的列子使用,一般应用到框架上,还会同时带上协议,例如:

上图为使用Core Location框架(移动设备定位)中,类及协议组成的委托。

上篇中,简单介绍了委托如何实现,在Core Location框架中,委托与协议共同使用,实现了对象间解耦及灵活性的问题,现在在上一份代码的基础上,新增加一个协议,即ManagerDelegate,此协议只有一个方法decideFrameDescription,这就构成了一个委托机制(delegation)(设计模式的一种)。

代码(点击这里下载)

//环境

//Mac OS X 10.3.7

//Xcode Version 4.3.2 (4E2002)  为了IOS 5.1 升级了新版本的xcode

[cpp]  view plain copy
  1. #import <Foundation/Foundation.h>   
  2. @protocol ManagerDelegate <NSObject> //协议   
  3. - (BOOL) decideFrameDescription;  
  4. @end  

[cpp]  view plain copy
  1. #import <Foundation/Foundation.h>  
  2. @protocol ManagerDelegate <NSObject> //协议  
  3. - (BOOL) decideFrameDescription;  
  4. @end  

通过Delegate实现此协议,即

[cpp]  view plain copy
  1. @interface Delegate : NSObject<ManagerDelegate>//绑定MangerDelegate   
  2. @property NSInteger number;  
  3. -(id)init;  
  4. @end  

[cpp]  view plain copy
  1. @interface Delegate : NSObject<ManagerDelegate>//绑定MangerDelegate  
  2. @property NSInteger number;  
  3. -(id)init;  
  4. @end  

[cpp]  view plain copy
  1. #pragma mark-   
  2. #pragma mark ManagerDelgate   
  3. //实现协议   
  4. -(BOOL) decideFrameDescription{  
  5.     return NO;  
  6.     //通过return YES 或者 NO,来控制框架的描述   
  7. }  
  8. @end  

[cpp]  view plain copy
  1. #pragma mark-  
  2. #pragma mark ManagerDelgate  
  3. //实现协议  
  4. -(BOOL) decideFrameDescription{  
  5.     return NO;  
  6.     //通过return YES 或者 NO,来控制框架的描述  
  7. }  
  8. @end  
最终框架会在根据用户在Delegate中协议的描述,完成框架里相应方法的变化,在本例中是

[cpp]  view plain copy
  1. @implementation MyFrameWork  
  2. @synthesize delegate,decide;  
  3. - (NSString *) description{  
  4.     if([self.decide decideFrameDescription]){  
  5.         return (@"I am a MyFrameWork");  
  6.     }  
  7.     else{  
  8.         return (@"I am a decided MyFrameWork");  
  9.     }  
  10. }  

[cpp]  view plain copy
  1. @implementation MyFrameWork  
  2. @synthesize delegate,decide;  
  3. - (NSString *) description{  
  4.     if([self.decide decideFrameDescription]){  
  5.         return (@"I am a MyFrameWork");  
  6.     }  
  7.     else{  
  8.         return (@"I am a decided MyFrameWork");  
  9.     }  
  10. }  
在框架中需声明协议接受的对象类型,如下

[cpp]  view plain copy
  1. @protocol ManagerDelegate; //对协议声明的引用   
  2. @interface MyFrameWork : NSObject{  
  3. }  
  4. @property (nonatomic,assign)NSObject   *delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类   
  5. @property (nonatomic,assign)id<ManagerDelegate> decide;//声明需要接受实现了ManagerDelegate协议的对象   
  6. - (id)init;  
  7. - (void) callDelegate;  
  8. @end  

[cpp]  view plain copy
  1. @protocol ManagerDelegate; //对协议声明的引用  
  2. @interface MyFrameWork : NSObject{  
  3. }  
  4. @property (nonatomic,assign)NSObject   *delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类  
  5. @property (nonatomic,assign)id<ManagerDelegate> decide;//声明需要接受实现了ManagerDelegate协议的对象  
  6. - (id)init;  
  7. - (void) callDelegate;  
  8. @end  
最终,我们通过在Delegate中实现ManagerDelegate协议,而框架通过decideFrameDescription的返回值,实现了改变。像在 Cocoa touch框架中,如果我们要使用一个picker(选取器),但框架不知道我们要的是几个组件的picker和每个组件的内容,所以需要在我们的ViewControler中实现<UIPickerViewDelegate>和<UIPickerViewDataSource>.如果在 numberOfComponentsInPickerView中返回2,完成numberOfRowsInComponent的组件选择,完成UIPickerViewDataSource协议。
运行显示效果如下图:


    <此例为其他工程截图>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值