原文 http://blog.csdn.net/lovefqing/article/details/8270111

委托(delegate)也叫代理是iOS开发中常用的设计模式。我们借助于protocol(参考博文:objective-c协议(protocol))可以很方便的实现这种设计模式。

什么是代理?

苹果的官方文档给了很清晰的解释:

Delegation is a simple and powerful pattern in which 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.

意译一下就是:代理是一种简单而功能强大的设计模式,这种模式用于一个对象“代表”另外一个对象和程序中其他的对象进行交互。 主对象(这里指的是delegating object)中维护一个代理(delegate)的引用并且在合适的时候向这个代理发送消息。这个消息通知“代理”主对象即将处理或是已经处理完了某一个事件。这个代理可以通过更新自己或是其它对象的UI界面或是其它状态来响应主对象所发送过来的这个事件的消息。或是在某些情况下能返回一个值来影响其它即将发生的事件该如何来处理。代理的主要价值是它可以让你容易的定制各种对象的行为。注意这里的代理是个名词,它本身是一个对象,这个对象是专门代表被代理对象来和程序中其他对象打交道的。

Cocoa中的代理

Cocoa Touch框架里大量使用了代理这种设计模式,在每个UI控件类里面都声明了一个类型为id的delegate或是dataSource,查看Cocoa的头文件可以发现很多如下的属性:

@property(nonatomic, assign)id<UIActionSheetDelegate> delegate;   // weak reference

通常格式为@property(nonatomic, assign)id<protocol_name> delegate;  即这个代理要遵循某一个协议,也就是说只有遵循了这个协议的类对象才具备代理资格。这同时也要求了代理类必须在头文件中声明遵循这个protocol_name协议并实现其中的@required方法,@optional的方法是可选的。

以UIActionSheet为例,我们定义一个View,当点击这个View中的某一个按钮时触发UIActionSheet, 当用户对UIActionSheet完成了某一项操作,比如Destruct按钮被按下,或是cancel按钮被按下,UIActionSheet会发送消息给delegate,由delegate完成对用户操作的响应,比如打印一个字符串到屏幕上。图示说明如下:

首先,我们创建一个基于tab的工程,在FirstViewController.h中添加代码,使这个类遵循UIActionSheetDelegate协议:

@interface FirstViewController : UIViewController <UIActionSheetDelegate>

在View中添加一个按钮用于触发这个ActionSheet,然后编写这个按钮的响应代码:

- (IBAction)invokeActionSheet:(id)sender {  

    UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"Delegate Example"
delegate:self // telling this class(ViewController) to implement UIActionSheetDelegate
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Destruct"
otherButtonTitles:@"Button 1",@"Button 2",nil]; [actionSheet showInView:self.tabBarController.view];
[actionSheet release];
}

注意,上面有一个很重要的设置就是参数中有个delegate:self,这个设置就是指明了UIActionSheet的代理为self, 也即FirstViewController。

然后在FirstViewController.m中实现UIActionSheetDelegate中的方法:

 
#pragma mark --UIActionSheet delegate methods
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
self.myTextFromActionSheet.text = @"Action Destructed!";
break;
case 1:
self.myTextFromActionSheet.text = @"Action Button 1 Clicked!";
break;
case 2:
self.myTextFromActionSheet.text = @"Action Button 2 Clicked!";
break;
case 3:
self.myTextFromActionSheet.text = @"Cancel Button Clicked!";
break;
default:
break;
} }

上面的几步我们完成了对Cocoa中UIActionSheet已有代理的运用。然而我们很多时候需要自己编写定制的代理,该如何实现呢?

自定义代理

我们要做的是,创建一个view,自定义一个代理实现更新这个view中的字符串。上面我们已经创建好了一个tab工程,借用里面的second view。我们拖一个按钮到上面命名为ChangeText,响应函数为- (IBAction)changeText:(id)sender;点击这个按钮进入一个modal view 名为ChangeTextView,我们在ChangeTextView中输入一个字符串并在退出这个view后把这个字符串更新到second view上面。如何实现modal view和second view之间的数据传递呢?那就是代理!谁的代理?ChangeTextView的代理!因为我们直接在ChangeTextView中输入数据,需要由代理把输入的字符串反馈到second view上面去。

1、创建一个新的类ChangeTextViewController,并创建相应的xib文件。

2、在ChangeTextViewController.h中声明一个协议ChangeTextViewDelegate:

 
@protocol ChangeTextViewDelegate <NSObject>  

- (void) textEntered:(NSString*) text;  

@end  

和UIActionSheet类似,在ChangeTextViewController中我们也需要添加一个代理的声明:

@property (assign, nonatomic) id<ChangeTextViewDelegate> delegate;  

3、我们还需要在ChangeTextViewController.xib中添加一个按钮save,当按下这个按钮会返回到second view中,并更新字符串。对save按钮的响应函数为:

- (IBAction)saveButtonClicked:(id)sender {
//Is anyone listening
if([delegate respondsToSelector:@selector(textEntered:)])
{
//send the delegate function with the amount entered by the user
[delegate textEntered:textEntered.text];
} [self dismissModalViewControllerAnimated:YES];
}

[delegate textEntered:textEntered.text];这句代码的含义就是ChangeTextViewController通知代理,textEntered这个事件发生了,对textEntered这个消息的实现,即如何响应这个textEntered的事件由代理来实现。在本例中,SecondViewController就是ChangeTextViewController对象的代理。所以,我们要对SecondViewController做相应的设置使其满足代理的条件。首先,在SecondViewController.h中声明遵循协议ChangeTextViewDelegate。然后编辑ChangeText按钮的响应函数- (IBAction)changeText:(id)sender;

- (IBAction)changeText:(id)sender {
ChangeTextViewController *CTViewController = [[ChangeTextViewController alloc] initWithNibName:@"ChangeTextViewController" bundle:nil];
//Assign this class to the delegate of ChangeTextViewController,
//remember to make thie ViewController confirm to protocol "ChangeTextViewDelegate"
//which is delared in file ChangeTextViewController.h
CTViewController.delegate = self;
[self presentModalViewController:CTViewController animated:YES];
}

注意,CTViewController.delegate = self;这句实现了SecondViewController成为ChangeTextViewController对象的代理。

本文对应的源代码下载:http://download.csdn.net/detail/lovefqing/4874331

IOS设计模式--代理 (委托)的更多相关文章

  1. iOS设计模式 - 代理

    iOS设计模式 - 代理 原理图 说明 1. 代理模式大家都用过,但用抽象基类NSProxy实现代理估计鲜有人用 2. 本人用NSProxy实现了代理模式,对于理解消息转发机制有点帮助 源码 http ...

  2. iOS delegate, 代理/委托与协议.

    之前知知道iOS协议怎么写, 以为真的跟特么java接口一样, 后来发现完全不是. 首先, 说说应用场景, 就是当你要用一个程序类, 或者说逻辑类, 去控制一个storyboard里面的label, ...

  3. iOS 设计模式-委托模式

    委托是指给一个对象提供机会对另一对象中的变化做出反应或者相应另一个对象的行为.其基本思想是协同解决问题. Delegate的使用场合 对象A内部发生了一些事情,想通知对象B 对象B想监听对象A内部发生 ...

  4. iOS书摘之Objective-C编程之道 iOS设计模式解析

    来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...

  5. IOS设计模式之一(MVC模式,单例模式)

    iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...

  6. IOS设计模式之三:MVC模式

    IOS设计模式之三:MVC模式   模型-视图-控制器 这个模式其实应该叫做MCV,用控制器把model与view隔开才对,也就是model与view互相不知道对方的存在,没有任何瓜葛,他们就像一个团 ...

  7. JAVA设计模式——代理(静态代理)

    定义 为其它的对象提供一种代理,以控制这个对象的访问 使用场景 当不想直接访问某个对象的时候,就可以通过代理 1.不想买午餐,同事帮忙带 2.买车不用去厂里,去4s店 3.去代理点买火车票,不用去车站 ...

  8. iOS设计模式 - 中介者

    iOS设计模式 - 中介者 原理图 说明 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 注:中介者对象本身没有复用价值 ...

  9. iOS 设计模式

    很赞的总结 iOS Design Patterns 中文版 IOS设计模式之一(MVC模式,单例模式) IOS设计模式之二(门面模式,装饰器模式) IOS设计模式之三(适配器模式,观察者模式) IOS ...

随机推荐

  1. 集合问题 离线+并查集 HDU 3938

    题目大意:给你n个点,m条边,q个询问,每条边有一个val,每次询问也询问一个val,定义:这样条件的两个点(u,v),使得u->v的的价值就是所有的通路中的的最长的边最短.问满足这样的点对有几 ...

  2. css float left right 中间空间城数据无法显示

    css float left right 中间空间城数据无法显示 是由于设定了width具体值太小造成,简单用%值或不设置.

  3. zf-启动项目报错Server 127.0.0.1 has no instance named dlx 解决办法

    由于百度出来的看不明白,于是我就在群里问,吴善如经理说:你这个问题我上次给李宽看过,用端口连,把instance去掉 然后我去掉之后 项目过程能够成功运行了,原来是这样

  4. 实例:SSh结合Easyui实现Datagrid的分页显示

    近日学习Easyui,发现非常好用,界面很美观.将学习的心得在此写下,这篇博客写SSh结合Easyui实现Datagrid的分页显示,其他的例如添加.修改.删除.批量删除等功能将在后面的博客一一写来. ...

  5. listView上拉刷新下拉加载

    xlistview_header.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLa ...

  6. UIApearance

    转载自:http://www.cocoachina.com/ios/20150723/12671.html 文章开头先援引一下Mattt Thompson大神在UIApearance里的一句话吧: 1 ...

  7. FTP 1.0

    自己写的可以实现文件的下载(必须自己知道文件名),还有很多要优化. 譬如:不能看可以下载的文件,输入错误无法处理,不能处理多个用户,每次只能下载一个结束,服务器没有完成守护进程:没有用函数封装,简化m ...

  8. [转]Qt5.0 连接 webkit 错误解决

    新版的qt5.0把webkit拆分为webkit和webkitwidgets两个部分,所以如果遇到错误: Undefined symbols for architecture x86_64:“QWeb ...

  9. 个人学习FPGA的初步过程

    对于FPGA,完全是从零开始学习,简单讲述一下我个人学习FPGA的经历吧: 没有开发板的日子.说真的要我掏腰包买开发板觉得是一件非常奢侈的事情.理由1:现成的东西,背后影藏诸多诡异的事情我们是无法体会 ...

  10. 关于Google Chrome 浏览器的一些命令及用法

    http://blog.csdn.net/zyz511919766/article/details/7356306 一些Chrome的地址栏命令(这些命令会不停的变动,所有不一定都是好用的) 在Chr ...