委托模式在Cocoa Touch框架和Cocoa框架中都有很多的应用。例如在应用启动的时候需要的一个类:UIApplication。在程序的入口函数main函数里面:
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([WBAppDelegate class])); } }
UIApplication的方法UIApplicationMain函数设置了它的委托类:WBAppDelegate。UIApplication不直接依赖于WBAppDelegate类,而是依赖于UIApplicationDelegate协议,WBAppDelegate类实现协议UIApplicationDelegate,WBAppDelegate是一个委托类。
委托是为了降低一个对象的复杂度和耦合度,使其能够更具通用性而将一些处理置于委托对象中得编码方式。通用类因为通用性而变成框架类,框架类保持委托对象的指针,并在特定的时刻向委托对象发送消息。消息可能只是通知委托对象做一些事情,也可能是对委托对象的控制。
下面通过一个班主任老师和班长的例子来介绍一下委托模式的实现原理和应用场景。老师(Teacher)为了更好的管理班级需要任命一位同学为班长(Monitor),老师希望班长能帮助他做两件事情:
1、发布一些信息(sendMessage)
2、收集同学们的一些情况(collectSomething)
也就是说,老师为了更好地工作,需要将这两件事情委托给班长来做,然而要成为班长,需要实现一个协议,这个协议要求能够处理“发布一些信息”和“收集同学们的一些情况”。先定义一个Teacher类:
#import @protocol WBTeacherDelegate @required - (void)sendMessage; - (void)collectSomething; @end @interface WBTeacher : NSObject @property (nonatomic, weak) id delegate; @end
// // WBTeacher.m // DesignPatternsDemo // // Created by 韩学鹏 on 15/6/22. // Copyright (c) 2015年 韩学鹏. All rights reserved. // #import "WBTeacher.h" @implementation WBTeacher @end
Teacher类就是上面所说的通用类,它通过delegate属性保持委托对象的引用,委托对象就是班长,他需要实现协议WBTeacherDelegate。WBTeacherDelegate协议规定了两个方法:sendMessage和collectSomething。
下面来实现班长类:
// // WBMonitor.h // DesignPatternsDemo // // Created by 韩学鹏 on 15/6/22. // Copyright (c) 2015年 韩学鹏. All rights reserved. // #import #import "WBTeacher.h" @interface WBMonitor : NSObject @end
// // WBMonitor.m // DesignPatternsDemo // // Created by 韩学鹏 on 15/6/22. // Copyright (c) 2015年 韩学鹏. All rights reserved. // #import "WBMonitor.h" @implementation WBMonitor - (id)init { self = [super init]; WBTeacher *teacher = [[WBTeacher alloc] init]; teacher.delegate = self; [teacher doSomething:0]; [teacher doSomething:1]; return self; } - (void)sendMessage { NSLog(@"monitor:send message..."); } - (void)collectSomething { NSLog(@"monitor:collect something..."); } @end
然后修改一下Teacher类:
// // WBTeacher.h // DesignPatternsDemo // // Created by 韩学鹏 on 15/6/22. // Copyright (c) 2015年 韩学鹏. All rights reserved. // #import @protocol WBTeacherDelegate @required - (void)sendMessage; - (void)collectSomething; @end @interface WBTeacher : NSObject @property (nonatomic, weak) id delegate; - (void)doSomething:(int)tag; @end // // WBTeacher.m // DesignPatternsDemo // // Created by 韩学鹏 on 15/6/22. // Copyright (c) 2015年 韩学鹏. All rights reserved. // #import "WBTeacher.h" @implementation WBTeacher - (void)doSomething:(int)tag { if (!_delegate) { return; } switch (tag) { case 0: [_delegate sendMessage]; break; case 1: [_delegate collectSomething]; break; default: break; } } @end
可以看到,委托协议WBTeacherDelegate定义了两个方法,他得实现类是WBMonitor。WBTeacher类中定义doSometing:方法是为了调试方便模拟老师向班长发送消息的方法。
委托对象和通用类通过WBMonitor类中的init方法中的teacher.delegate = self来建立关系。调试输出内容如下:
2015-06-22 09:08:47.991 DesignPatternsDemo[26365:607] monitor:send message... 2015-06-22 09:08:47.993 DesignPatternsDemo[26365:607] monitor:collect something...
附WBTeacher和WBMonitor类的下载地址:委托模式