delegate初探

在ios开发中,我们常常会用到类似例如以下的对话框:

因此,例如以下这段代码我们也就非常熟悉了:

- (IBAction)showSheet:(id)sender {
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"title,nil时不显示"
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:@"确定"
otherButtonTitles:@"第一项", @"第二项",nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[actionSheet showInView:self.view];
}

当中initWithTitle函数的第二个參数为delegate,那么是什么呢? 我们到它的头文件里看看。

initWithTitle这个函数的声明例如以下 :

- (id)initWithTitle:(NSString *)title delegate:(id<UIActionSheetDelegate>)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;

是的,上面这个巨长无比的函数声明就是initWithTitile函数,oc这个语言本身给我的感觉就是繁杂。废话不多说,我们直接看到delegate參数的类型是id<UIActionSheetDelegate>。直接看UIActionSheetDelegate的声明:

@protocol UIActionSheetDelegate <NSObject>
@optional // Called when a button is clicked. The view will be automatically dismissed after this call returns
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex; // Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button.
// If not defined in the delegate, we simulate a click in the cancel button
- (void)actionSheetCancel:(UIActionSheet *)actionSheet; - (void)willPresentActionSheet:(UIActionSheet *)actionSheet; // before animation and showing view
- (void)didPresentActionSheet:(UIActionSheet *)actionSheet; // after animation - (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex; // before animation and hiding view
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation @end

能够看到UIActionSheetDelegate是一个普普通通的协议,在@optional以下有六个函数,这些函数都是可选实现的,每一个函数相应的是UIActionSheet中每一个button的点击事件处理。当然最后两个函数是依照索引来区分Button对象的。

delagate的实现

协议与delegate不是同一概念,协议是语言级别的特性,而delegate是借助协议来的实现的一种设计模式,事实上就是代理模式。通过注入

代理对象实现对应的功能。

事实上它的主要功能也就是实现回调,与Java中的listener一样。

以下以一个演示样例来说明 :

// ButtonClickDelegate协议
@protocol ButtonClickDelegate <NSObject> -(void) onClick: (id) sender ; @end // view的声明。实现了ButtonClickDelegate协议
@interface UIView : NSObject <ButtonClickDelegate >
{
@protected id<ButtonClickDelegate> clickDelegate ;
} // 点击事件代理。因此UIView实现了ButtonClickDelegate协议,因此自己能够为自己代理。
@property (nonatomic, strong) id<ButtonClickDelegate> clickDelegate ;
// 点击view的触发函数
-(void) performClick ; @end // view的实现
@implementation UIView @synthesize clickDelegate ; // 默认的点击事件
-(id) init
{
self = [super init] ;
if ( self ) {
clickDelegate = self ;
}
return self;
} // 点击view的事件的默认处理
-(void) onClick: (id) sender
{
NSLog(@"点击view的默认处理函数.") ;
} // 点击事件
-(void) performClick
{
[clickDelegate onClick: self ] ;
} @end // ViewController声明, 实现了ButtonClickDelegate协议,能够作为UIView的代理
@interface ViewController : NSObject <ButtonClickDelegate>
@property (nonatomic, strong) UIView* parenView ;
@end // ViewController实现
@implementation ViewController -(void) onClick:(id)sender
{
NSLog(@"ViewController来实现点击事件") ;
} @end

main函数:

// main
int main(int argc, const char * argv[])
{ @autoreleasepool {
// view对象
UIView* view = [[UIView alloc] init] ;
[view performClick] ; // 构建一个ViewController对象
ViewController* controller = [[ViewController alloc] init] ;
view.clickDelegate = controller ;
[view performClick] ; }
return 0;
}

首先创建了一个UIView对象view, 然后调用performClick函数,此时view没有设置delegate,可是因为自己实现了ButtonClickDelegate协议,因此能够为自己代理该点击事件。然后我们创建了ViewController对象controller, 而且将该对象设置为view对象的delegate。 然后运行performClick函数,此时在performClick函数中

会运行ViewController中的onClick函数。即controller代理了view的点击事件处理。输出结果例如以下 :

点击view的默认处理函数.
ViewController来实现点击事件

delegate与Java中的Listener

delegate与Java中的Listener的功能大致是同样的,比方我们看看Android中一个button的点击事件的处理。

	Button	mJumpButton = (Button) findViewById(R.id.button_jump);
mJumpButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});

当中的Button就相当于上文中的UIView,而其setOnClickListener就相当于delegate属性的设置方法。OnClickListener就扮演了上文中ButtonClickDelegate的角色,

onClick方法更是如出一辙。事实上每一个平台大体上的设计思路也都是非常相近的,观察不同平台的对照实现更easy理解吧。

delegate与id类型

我们在声明一个delegate对象是的形式是例如以下这种 : 
// 点击事件代理,因此UIView实现了ButtonClickDelegate协议。因此自己能够为自己代理。
@property (nonatomic, strong) id<ButtonClickDelegate> clickDelegate ;

注意这里的类型是id<ButtonClickDelegate>;这表明该delegate对象能够是随意类型,可是该类型必须实现ButtonClickDelegate协议,也能够说成该类型必须採用正式协议ButtonClickDelegate。这个就非常像Java中的泛型。比如我们能够在Java中这样使用泛型,

void setData(List<? extends Order> myorders) ;

在setData函数中接受的參数为元素类型为Order子类的List集合,与id<ButtonClickDelegate>是不是又非常相似呢?

Objective-c中的delegate浅析的更多相关文章

  1. jquery中on/delegate的原理

    jquery中on/delegate的原理 早期版本中叫delegate, 后来有过live函数,再后来统一用on.下面的方法等效: // jQuery 1.3 $(selector).(events ...

  2. 浅谈c#中的delegate和event了

    一.开篇忏悔 对自己最拿手的编程语言C#,我想对你说声对不起,因为我到现在为止才明白c#中的delegate和event是怎么用的,惭愧那.好了,那就趁着阳光明媚的早晨简单来谈谈delegate和ev ...

  3. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  4. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  5. C#中的Delegate

    谈C#中的Delegate http://www.cnblogs.com/hyddd/archive/2009/07/26/1531538.html

  6. 谈C#中的Delegate

    引言 Delegate是Dotnet1.0的时候已经存在的特性了,但由于在实际工作中一直没有机会使用Delegate这个特性,所以一直没有对它作整理.这两天,我再度翻阅了一些关于Delegate的资料 ...

  7. c#中的delegate(委托)和event(事件)

    c#中的delegate(委托)和event(事件) 一.delegate是什么东西? 完全可以把delegate理解成C中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能 ...

  8. ios中关于delegate(委托)的使用心得

    ios中关于delegate(委托)的使用心得 分类: iOS开发2012-05-15 10:54 34793人阅读 评论(9) 收藏 举报 iosuiviewtimerinterfaceprinti ...

  9. C#中的委托(Delegate)和事件(Event)

    原文地址:C#中的委托(Delegate)和事件(Event) 作者:jiyuan51 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式--观察者(Obs ...

随机推荐

  1. 2016北京集训测试赛(十一)Problem C: 树链问题

    Solution 智障暴力题, 每个点维护一下子树信息, 树剖就好了. 我居然还傻了写了一发毛毛虫... #include <cstdio> #include <cctype> ...

  2. ssh配置含义解释

    ssh包括客户端配置(ssh_config)和服务端配置(sshd_config) 一.客户端配置ssh_config,客户端软件有SecureCRT.putty.Xshell等 “#”表示注释,虽然 ...

  3. 通达OA 小飞鱼工作流在线培训教程(七)工作流应用的意义及基础设置(图文)

    这个课程计划已经有一段时间了,经过这段时间结合实际网络教学又进行了一些总结,这里将陆续为大家呈现相关的工作流设计开发课程. 同一时候线上的视频教学课程也将立即上线,欢迎朋友们的关注. 首先介绍一些工作 ...

  4. mongodb配置副本集(多台服务器间的副本集搭建) replica[ˈrɛplɪkə]

    副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,并且解决了“主节点挂掉了,整个集群内会自动切换”的问题.我们来看看mongoDB副本集的架构图: 由图可以看到客户端连接到整个副本集 ...

  5. Node.js学习笔记(3)——关于回调函数和函数的回调

    说明:本人是node.js的初学者,尝试向别人解释这是怎么回事是自我学习的一个好方法.如果你发现有些地方并不是那么正确,欢迎提出来让我知道以便修正,共同进步,谢过^_^.       欢迎交流,本人微 ...

  6. Ubuntu安装vncserver实现图形化远程桌面

    安装 apt-get update apt-get install vnc4server 开启vnc服务 vncserver 首次启动会要求设置密码,后面可以使用vncpasswd修改: 看到 New ...

  7. HDOJ2084数塔问题

    数塔问题 题目要求从顶层走究竟层.若每一步仅仅能走到相邻的结点,求经过的结点的数字之和最大值. 非常经典的DP,能够这样考虑,要求从塔顶到塔底最大路径之和.计算时能够考虑自底向上,走最后一步所选的数一 ...

  8. Key-Value键值存储原理初识(NOSQL)

    NO-Sql数据库:Not Only不仅仅是SQL 定义:非关系型数据库:NoSQL用于超大规模数据的存储.(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据).这些类型的数据存储不需要固 ...

  9. ubuntu 安装时遇到 hash sum mismatch 处理方法

    ubuntu安装大软件时,下载经常容易出错,hash sum mismatch是其中一种,说到底还是网络不好,重试很多遍都是这个错误,最后的解决方案是把mismatch说的那个链接用firefox打开 ...

  10. 30天自制操作系统(二)汇编语言学习与Makefile入门

    1 介绍文本编辑器 这部分可直接略过 2 继续开发 helloos.nas中核心程序之前的内容和启动区以外的内容先不讲了,因为还涉及到一些软盘方面的知识. 然后来讲的是helloos.nas这个文件 ...