Delegate

delegate&protocol

delegate(委托/代理)是iOS开发中常用的设计模式,表示将一个对象的部分功能转交给另一个对象。借助protocol可以很方便实现这中设计模式。

应用场景:

  1. 通知与监听: 详见 delegate,notifucation,KVO三种模式实现通信的优缺点

    苹果系统自带:

  2. UITabelView


    1. oc 一个类只能继承一个父类,但代理可以使一个类继承多个协议。
      这样一个类 可以从多个 类中 拿到方法 实现 扩展

什么是delegate?下面是官方文档解释

>
Delegation is a simple and powerful pattern in whick one object in a program acts on behalf of,or in coordination with,another object.The delegating object keeps a reference to the other
object-the delegate -and at the appropriate time sends a message to it.The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.

白话文:

你需要做一件事情,你自己不想动手,委托给 delegate 处理,为了避免所托非人,delegate 需要遵守一个你和 delegate 都能接受的 protocol。一个类只要声明它遵守了某个你想要的 protocol,你就能把它信认为是你的 delegate。
生活示例:很多土豪老板都是大忙人,有多个秘书或者助理,老板只想躺着输数钱就好了,接电话、订餐等等这些杂事,统统交给秘书(delegate)去处理就好了,至于接电话或者订餐的具体注意事项,秘书早就跟老板有了约定(protocol)。

说明:(1)官方解释中 delegation 是个名词,它本身是一个对象,专门代表被委托对象来和程序中其他对象交互。
(2)虽说官方文档有的时候显得抽象,但是很多时候必须读 Apple 官方文档,因为 Apple 官方文档的解释是最精确的


Protocol

凡是支持 delegate 的对象,其背后都有一个相应的协议 protocol(C# 或者 Java 语言中称之为接口 interface),声明可以向该对象的 delegate 对象发送的消息。定义协议,就是创建一个属性和方法清单。如果一个类实现了某个协议中规定的方法,称这个类遵守这个协议。当一个类遵守一个协议时,就是向编译器做出了承诺:它实现了这个协议中列出的所有属性和方法。除此之外,它还可以有其他很多属性或方法,另外,也可以同时遵守多个协议。


Cocoa Touch 中的delegate

使用 Xcode 创建一个工程时,Xcode 自动生成的 AppDelegate.h& AppDelegate.m两个文件,就可以看到 delegate 的使用。AppDelegate.h如下所示:

   #import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

AppDelegate.h 中,AppDelegate类声明了遵守 UIApplicationDelegate协议。查看 UIApplicationDelegate协议包含了哪些属性和方法

@protocol UIApplicationDelegate<NSObject>
@optional
- (void)applicationDidFinishLaunching:(UIApplication *)application;- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(6_0);
  ;
  ;
  ;
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
 ;
 ;
 ;

由于UIApplicationDelegate协议中属性和方法太多,只列出部分供展示在UIApplicationDelegate协议中,由关键字@optional可知方法都是可选的。协议所声明的方法可以是必需的(@required)或是可选的(@optional)。默认都是必需的。委托协议中的方法通常都是可选的。

AppDelegate.m中,实现了应用生命周期的方法(均在协议UIApplicationDelegate定义的可选方法):

@implementation AppDelegate

#pragma mark - Application lifecycle methods

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return YES;}
-(void)applicationWillResignActive:(UIApplication *)application {}
- (void)applicationDidEnterBackground:(UIApplication *)application {}
 - (void)applicationWillEnterForeground:(UIApplication *)application {}
 - (void)applicationDidBecomeActive:(UIApplication *)application {}
- (void)applicationWillTerminate:(UIApplication *)application {}

那协议UIApplicationDelegate有什么作用呢?举个例子:大家都有深刻体会,在 iPhone 上使用一个 App 过程中,一个来电或者锁屏会让 App 进入后台甚至被终止,此外还有其它情况也会导致 App 受到干扰,这时会产生一些系统事件,UIApplication会通知它的 delegate对象,让 delegate 来处理这些事件。

怎么使用 delegate? - 自定义 delegate

Talk is cheap.Show me the code. ~Linus Torvalds

* 前三步(委托者 老板):1.声明 delegate 原型;2.声明 delegate 变量; 3.实现delegate 方法 功能(功能的具体实现在这里)*

后三步(被委托者 秘书一般是控制器):4.声明实现(遵守) delegate;5.设置 delegate 的值(设置监听者self-控制器) 6.调用 delegate 方法 进行实现


前面举了老板跟秘书的示例,现在我们就简单实现一下这个示例。

step1 : 声明 delegate原型,即定义一个` protocol

// BossDelegate.h
#import <Foundation/Foundation.h>
@class Boss;
@protocol BossDelegate <NSObject>
@optional
//接电话
- (void)tel:(Boss *)theBoss;
//订餐- (void)buyFood:(Boss *)theBoss;
@end

step2 : 委托者 (老板) 声明一个delegate变量

// Boss.h
#import <Foundation/Foundation.h>
#import "BossDelegate.h"
@interface Boss : NSObject
//声明 delegate 变量
@property (nonatomic, weak) id<BossDelegate> delegate;
@end

备注:iOS SDK 中几乎所有的委托都是弱引用属性(weak),这是为了避免对象及其delegate之间产生强引用循环。

step3: 委托者(老板)调用 delegate内的方法:

注意:

这其实就是 协议中 方法的功能的具体实现,被委托者(控制器 后3步实现)

到时 直接实现这个方法就行

// Boss.m
#import "Boss.h"
@implementation Boss
- (id)init { 
self = [super init]; 
if (self) { 
//
} 
return self;
}
- (void)callSecretary {
 //调用 delegate 的方法
[_delegate tel:self]; 
[_delegate buyFood:self];
}
@end

step4: 被委托者(秘书)声明实现(遵守) delegate

// Secretary.h
#import <Foundation/Foundation.h>
#import "BossDelegate.h"
//声明实现 delegate
@interface Secretary : NSObject<BossDelegate>
@end

step5: 设置delegate的值

// main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "Boss.h"
#import "Secretary.h"
int main(int argc, char * argv[]) {
 @autoreleasepool { 
Boss *boss = [[Boss alloc] init]; 
Secretary *sec = [[Secretary alloc] init];  
//设置 delegate 的值
boss.delegate = sec;  
[boss callSecretary]; 

return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 
}
}

step 6 : 被委托者(秘书)(调用)来实现 delegate方法

// Secretary.m
#import "Secretary.h"
@implementation Secretary
- (id)init { 
self = [super init]; 
if (self) { 
//
} 
return self;
}
- (void)buyFood:(Boss *)theBoss { 
NSLog(@"秘书正在帮老板订餐...");
}
- (void)tel:(Boss *)theBoss { 
NSLog(@"秘书正在帮老板接听电话...");
}
@end

注意:

其实一般情况下 后三步都是在 控制器里面实现的。step5.之所以在main.m 实现,因为
这段代码没有控制器 程序根本不能执行,只能放在 main 的runLoop 里面

经过上述 6 步,一个完整的 delegate 就实现了。运行程序,结果如下:

2015-08-19 15:19:30.487 Protocol_Delegate_Demo[2230:174797] 秘书正在帮老板接听电话...
2015-08-19 15:19:30.489 Protocol_Delegate_Demo[2230:174797] 秘书正在帮老板订餐...

由程序运行结果可见,实际的动作是由委托者的 delegate(老板的秘书)去实现的。上述例子只是一个简单的示例,在 iOS 开发中经常用到 delegate 设计模式。比如:实现常见的UITableView就必须遵守TableViewDataSource, UITableViewDelegate两个协议。原理用法都是相通的,按照delegate使用的前三步、后三步,就可以把delegate这种设计模式应用好。

而且 UIView 就是通过 继承 遵守 UITableView 的 代理 变成 UITableView

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值