委托(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协议:

[cpp] view plaincopy
  1. @interface FirstViewController : UIViewController <UIActionSheetDelegate>

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

[cpp] view plaincopy
  1. - (IBAction)invokeActionSheet:(id)sender {
  2. UIActionSheet *actionSheet = [[UIActionSheet alloc]
  3. initWithTitle:@"Delegate Example"
  4. delegate:self // telling this class(ViewController) to implement UIActionSheetDelegate
  5. cancelButtonTitle:@"Cancel"
  6. destructiveButtonTitle:@"Destruct"
  7. otherButtonTitles:@"Button 1",@"Button 2",nil];
  8. [actionSheet showInView:self.tabBarController.view];
  9. [actionSheet release];
  10. }

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

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

[cpp] view plaincopy
  1. #pragma mark --UIActionSheet delegate methods
  2. - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
  3. switch (buttonIndex) {
  4. case 0:
  5. self.myTextFromActionSheet.text = @"Action Destructed!";
  6. break;
  7. case 1:
  8. self.myTextFromActionSheet.text = @"Action Button 1 Clicked!";
  9. break;
  10. case 2:
  11. self.myTextFromActionSheet.text = @"Action Button 2 Clicked!";
  12. break;
  13. case 3:
  14. self.myTextFromActionSheet.text = @"Cancel Button Clicked!";
  15. break;
  16. default:
  17. break;
  18. }
  19. }

上面的几步我们完成了对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:

[cpp] view plaincopy
  1. @protocol ChangeTextViewDelegate <NSObject>
  2. - (void) textEntered:(NSString*) text;
  3. @end

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

[cpp] view plaincopy
  1. @property (assign, nonatomic) id<ChangeTextViewDelegate> delegate;

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

[cpp] view plaincopy
  1. - (IBAction)saveButtonClicked:(id)sender {
  2. //Is anyone listening
  3. if([delegate respondsToSelector:@selector(textEntered:)])
  4. {
  5. //send the delegate function with the amount entered by the user
  6. [delegate textEntered:textEntered.text];
  7. }
  8. [self dismissModalViewControllerAnimated:YES];
  9. }

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

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

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

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

转载于:https://www.cnblogs.com/kenshinobiy/p/4741465.html

iOS设计模式——委托(delegate)相关推荐

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

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

  2. C# 委托(Delegate) 事件(Event)应用详解

    委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每 ...

  3. iOS设计模式 - 生成器

    iOS设计模式 - 生成器 原理图 说明 1. 将构建复杂对象的过程拆分成一个一个的模块,通过统一的指导者来指导对象的构建过程称之为生成器模式 2. 生成器模式适合用于构建组合的对象 源码 https ...

  4. iOS设计模式四部曲(三):行为型模式 内附Demo

    本篇是四部曲的第三篇,第一篇请点这里iOS设计模式四部曲(一):创建型模式,第二篇请点击这里iOS设计模式四部曲(二):结构型模式.由于个人能力有限,文中难免有一些遗漏或者错误,请各位看官不吝赐教!谢 ...

  5. iOS设计模式 - 备忘录

    iOS设计模式 - 备忘录 原理图 说明 1. 在不破坏封装的情况下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态 2. 本人已经将创建状态与恢复状态 ...

  6. iOS设计模式 - 组合

    iOS设计模式 - 组合 原理图 说明 将对象组合成树形结构以表示"部分-整体"的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 & ...

  7. C#委托(delegate、Action、Func、predicate)和事件

    C#委托(delegate.Action.Func.predicate)和事件 - 园子的蜗牛 - 博客园 C#之委托 - 摸鱼王 - 博客园 C++函数指针与C#委托之间有何联系 - 51CTO.C ...

  8. iOS设计模式 - 享元

    iOS设计模式 - 享元 原理图 说明 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分 ...

  9. iOS设计模式 - 迭代器

    iOS设计模式 - 迭代器 原理图 说明 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 源码 https://github.com/YouXianMing/iOS-Des ...

最新文章

  1. 基于HTML5的WebGL结合Box2DJS物理应用
  2. jittor自定义矩阵乘法(图解矩阵乘法)
  3. 洛谷P5174 圆点
  4. java版b2b2c社交电商spring cloud分布式微服务(七)springboot开启声明式事务
  5. MySQL索引的创建、删除和查看
  6. matlab ssb,MatlabSSB信号的仿真分析.doc
  7. Portlet开发指南第三章
  8. 区分.net、c#、asp.net三者间的关系
  9. GlusterFS vs. CephFS性能对比研究(一)
  10. jest (让人愉悦的测试框架)
  11. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
  12. 单图像超分辨率重建示例代码解析
  13. ax88772c linux驱动下载,ax88772c以太网驱动问题
  14. Codeforces 777D Cloud of Hashtags(思维 + 暴力)
  15. 华为5g服务器硬件供应商,华为发布5G多模终端芯片和商用终端
  16. matlab设置坐标数值,Matlab中描点及坐标设置相关
  17. 用Python的Pandas和Matplotlib绘制股票唐奇安通道,布林带通道和鳄鱼组线
  18. Android studio编译错误
  19. RENIX_802.3ah功能介绍(下)——网络测试仪实操
  20. 运放单电源供电和双电源供电

热门文章

  1. Fortinet 修复严重漏洞,可导致未认证黑客以最高权限执行任意代码
  2. 美国特勤局发布十大网络通缉犯名单
  3. “依赖混淆”供应链攻击现身 微软苹果特斯拉优步等超35家企业内网失陷
  4. 半岛电视台员工遭iOS iMessage app零点击0day 漏洞利用攻击
  5. atomic、锁、多线程
  6. 以物载道,探享生活艺术,LEXUS雷克萨斯开启中国新匠精神巡展
  7. nginx+uwsgi+django环境部署部署
  8. 呼叫中心职场EQ与情绪压力管控(时刻提醒自己!)
  9. 如何限制用户在某一时间段多次访问接口
  10. 股票分析之主力资金排序分析