委托在IOS开发框架Cocoa Touch 中经常使用,其含义是一个类的对象要求委托对象执行它的某些操作。委托机制实际是种设计模式,通过此种机制,能降低对象间的耦合。还是不继续说概念了,直接上定义代码(点这里下载)
//环境
//Mac OS X 10.3.7
//Xcode Version 4.2.1
//使用的是Xcode的Command Line Tool工程,结果由命令行输出
- @interface MyFrameWork : NSObject{
- }
- @property (nonatomic,assign)NSObject * delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类
- - (id)init;
- - (void) callDelegate;
- @end
- #import "MyFrameWork.h"
- @implementation MyFrameWork
- @synthesize delegate;
- - (NSString *) description{
- return (@"I am MyFrameWork");
- }
- -(id) init{
- self = [super init];
- if (self){
- }
- return self;
- }
- <pre name="code" class="cpp">-(void)callDelegate{
- //通过delegate指针访问类Delegate的description方法
- NSString *string = [self.delegate description];
- //发现在最新版的编译器里面NSLog为了安全(支持ARC),只接受格式化的字符串,因为NSLog底层也是用printf来格式化输出的。
- //NSLog(str); // warning
- // NSLog(@"%@", str); // solution
- // NSLog(str, nil); // solution
- NSLog(string,nil);
- }
- @interface Delegate : NSObject
- @property NSInteger number;
- -(id)init;
- @end
- #import "Delegate.h"
- @implementation Delegate
- @synthesize number;
- -(NSString *)description{
- self.number = self.number + 1;
- NSString *string = [[NSString alloc] initWithFormat:@"I am Delegate,%ld calls",self.number];
- return (string);
- }
- -(id)init{
- self = [super self ];
- if (self) {
- self.number =0;
- }
- return self;
- }
- @end
上图为使用Core Location框架(移动设备定位)中,类及协议组成的委托。
在上篇中,简单介绍了委托如何实现,在Core Location框架中,委托与协议共同使用,实现了对象间解耦及灵活性的问题,现在在上一份代码的基础上,新增加一个协议,即ManagerDelegate,此协议只有一个方法decideFrameDescription,这就构成了一个委托机制(delegation)(设计模式的一种)。
//环境
//Mac OS X 10.3.7
//Xcode Version 4.3.2 (4E2002) 为了IOS 5.1 升级了新版本的xcode
- #import <Foundation/Foundation.h>
- @protocol ManagerDelegate <NSObject> //协议
- - (BOOL) decideFrameDescription;
- @end
通过Delegate实现此协议,即
- @interface Delegate : NSObject<ManagerDelegate>//绑定MangerDelegate
- @property NSInteger number;
- -(id)init;
- @end
- #pragma mark-
- #pragma mark ManagerDelgate
- //实现协议
- -(BOOL) decideFrameDescription{
- return NO;
- //通过return YES 或者 NO,来控制框架的描述
- }
- @end
最终框架会在根据用户在Delegate中协议的描述,完成框架里相应方法的变化,在本例中是
- @implementation MyFrameWork
- @synthesize delegate,decide;
- - (NSString *) description{
- if([self.decide decideFrameDescription]){
- return (@"I am a MyFrameWork");
- }
- else{
- return (@"I am a decided MyFrameWork");
- }
- }
在框架中需声明协议接受的对象类型,如下
- @protocol ManagerDelegate; //对协议声明的引用
- @interface MyFrameWork : NSObject{
- }
- @property (nonatomic,assign)NSObject *delegate;//委托对象的指针,类型为NSObject,即一切objective-c类的父类
- @property (nonatomic,assign)id<ManagerDelegate> decide;//声明需要接受实现了ManagerDelegate协议的对象
- - (id)init;
- - (void) callDelegate;
- @end
最终,我们通过在Delegate中实现ManagerDelegate协议,而框架通过decideFrameDescription的返回值,实现了改变。像在Cocoa touch框架中,如果我们要使用一个picker(选取器),但框架不知道我们要的是几个组件的picker和每个组件的内容,所以需要在我们的ViewControler中实现<UIPickerViewDelegate>和<UIPickerViewDataSource>.如果在numberOfComponentsInPickerView中返回2,完成numberOfRowsInComponent的组件选择,完成UIPickerViewDataSource协议。
运行显示效果如下图:
<此例为其他工程截图>