Objective-C 委托全方位解读

简介:

Delegate是运用Objective-C的运行时来实现的一种设计模式。
官方文档的描述位置:
iOS Library- > General- > Cocoa Fundamentals Guide- > Cocoa Design Patterns- > How Cocoa Adapts Design Patterns- > Decorator- > Delegation

你看文档给出的位置就可以知道它的大概作用了,它是装饰器的一种实现。如果你熟悉设计模式的话,可以知道装饰器是动态实现给一个对象添加一些额外职责的设计模式。如果不是很清楚的话,请google 装饰器 设计模式 或者 Design Patterns Decorator,了解更多。

那具体到Objective-C里,Delegate就是利用Objective-C 的运行时(Runtime)来实现动态的判断某对象是否存在,某对象是否实现了一些选择器(Selector),如果实现了,则通过调用该对象的某一选择器来帮助自己实现一些功能。

在实际使用当中,设计一个自己的类Class的AClassDelegate可以通过两种方式实现,一种是非正式协议,Informal Protocol。

正式协议,Protocol。比较新的类的设计都会使用Protocol是定义自己的Delegate方法,并为之标记可选还是必需实现。
当一个类会作为另一个类的Delegate的时候,需要实现该Delegate的Protocol,这意味着如果有标记@required的相应方法,那该类的实例必需实现该方法。@optional的方法就并不一定要实现。

举一个具体的例子:
UINavigationController的Delegate应该是很少用到的,我看了一下也应该是比较简单的Delegate的设计。

[cc lang="c"]
@protocol UINavigationControllerDelegate NSObject >

@optional

// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

@end
[/cc]

这个Delegate的方法都是可选实现的,不是必须的,所以通常大家比较少去主动用。
那分析一下这个Delegate,我们可以知道,这个Delegate的设计是UINavigationController在show某一个ViewController的时候会对它的Delegate进行一种类似通知的调用:“我即将展示某某ViewController了”,
那该Delegate可以通过实现这个方法进行相应的操作。

举一个具体实现的例子
[cc lang="c"]
// AZDelegationDemo.h
// Created by Aladdin Zhang on 8/24/11.

#import
@protocol AZDelegationDemoDelegate;
@interface AZDelegationDemo : NSObject{
idAZDelegationDemoDelegate > delegate;
NSMutableArray * shoppingList;
}
@property (nonatomic,assign) idAZDelegationDemoDelegate > delegate;
@end

@interface AZDelegationDemo (informal_protocol_delegate)
- (void)buyCoffee;
@end

@protocol AZDelegationDemoDelegate NSObject >
@required
- (void)buyPork;
@optional
- (void)buyMilk;
@end

// AZDelegationDemo.m
// Created by Aladdin Zhang on 8/24/11.

#import "AZDelegationDemo.h"

@implementation AZDelegationDemo
@synthesize delegate;
- (id)init{
self = [super init];
if (self) {
shoppingList = [NSMutableArray arrayWithCapacity:20];
}
return self;
}
- (void)buyStuff{
NSLog(@"My Shopping List %@",shoppingList);
}
- (void)weeklyShopping{
if (self.delegate&&[self.delegate conformsToProtocol:@protocol(AZDelegationDemoDelegate)]) {
[self.delegate performSelector:@selector(buyPork)];
if ([self.delegate respondsToSelector:@selector(buyMilk)]) {
[self.delegate performSelector:@selector(buyMilk)];
}else{
[shoppingList addObject:[NSString stringWithFormat:@"Milk"]];
}
if ([self.delegate respondsToSelector:@selector(buyCoffee)]) {
[self.delegate performSelector:@selector(buyCoffee)];
}else{
[shoppingList addObject:[NSString stringWithFormat:@"Coffee"]];
}
[self buyStuff];
}
}
@end
[/cc]
这是我刚刚为这个回答写的一个例子,基本上涵盖了一般用途的Delegate的设计,这里不对具体Delegate的实现进行说明了,和其他系统提供的Delegate的使用基本一致。

在这个例子中,我分别使用了分类(Category),即非正式协议,和协议(Protocol)来实现Delegate的设计。其实运用Objective-C的动态性,分类实现的协议和Protocol中的可选的协议方法,在调用上是一样的。使用正式协议,并标记为必需的好处是,可以通过编译器来帮助矫正不该出现的错误。

来自知乎

相关文章
|
JavaScript 前端开发 Java
Objective-C协议(protocol)和委托(delegate)的基本概念(★firecat推荐★)
Objective-C协议(protocol)和委托(delegate)的基本概念(★firecat推荐★)
252 0
|
iOS开发 开发者
Objective - C 面向对象高级特性 - 包装类 | 类处理 | 类别 | 扩展 | 协议 | 委托 | 异常处理 | 反射
http://blog.csdn.net/shulianghan/article/details/48876843 这个漂亮的文字阴影,搞不到啊,求指教 一. Objective-C 对象简单处理 1. 包装类 (1) 包装类简介 NSValue 和 NSNumber : 
2081 0
|
iOS开发
Objective-C中协议和委托
Objective-C中的协议(Protocol)类似于常用的接口,协议(Protocols)中定义的方法,在类中实现。<br> @protocol MyFirstProtocol<br> - (void)myFirstProtocolMethod;<br> @end<br> 在iPhone OS中,协议(Protocol)通常用来实现委托对象(Delegate Object)。委
1093 0
|
7月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
430 2
|
5月前
|
开发工具 iOS开发 容器
【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错
iOS Objective-C 应用连接Azure Storage时,若不关闭账号的匿名访问,程序能正常运行。但关闭匿名访问后,上传到容器时会出现错误:“Public access is not permitted”。解决方法是将创建容器时的公共访问类型从`AZSContainerPublicAccessTypeContainer`改为`AZSContainerPublicAccessTypeOff`,以确保通过授权请求访问。
【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错
|
7月前
|
缓存 开发工具 iOS开发
优化iOS中Objective-C代码调起支付流程的速度
优化iOS中Objective-C代码调起支付流程的速度
125 2
|
7月前
|
安全 JavaScript 前端开发
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
311 0
|
iOS开发 容器
iOS 代码规范格式 Objective-C(上)
iOS 代码规范格式 Objective-C
440 0
iOS 代码规范格式 Objective-C(上)
|
编译器 API iOS开发
iOS 代码规范格式 Objective-C(下)
iOS 代码规范格式 Objective-C(下)
242 0