在iOS 开发中, 搞清楚Delegate 是需要花些时间的。 Delegate 本来是软件架构设计的一种理念。对于像手机这样一个有限的设备,我们需要充分考虑到:内存要尽量省着用; 视图之间的关系要清晰。 如果你所开发的App ,仅仅是一个demo,是体现不出架构优势的。 但当你的App 需要处理海量数据, 而视图之间的关系又颇为复杂时,你将不得不考虑这些问题。
视图之间的关系,不仅仅是跳转,更重要的是视图之间数据的传递。当视图A 发生变化时,如何将这个变化告知视图B 呢? 举个例子吧。

如下图所示。

这是一个计算器App,支持函数的图形展示。 点击右上角的按钮,可弹出函数 列表。 这个列表是一个TableView;  函数图形的展示是另一个视图,我们称之为 GraphicView。  这个实例所展示的是: 当在Tableview选择不同的函数时,函数的绘制图形会随之改变。这里要解决的关键问题是, 如何将所选择的函数告知 函数图形视图? 

先说明下,这是基于Storyboard 创建的工程。 工程本身有些复杂,我们不再从头讲起,这里着重讲解 @protocol 的使用。

 通常,一个delegate的使用过程,需要经过五步:

1.     创建一个 delegate;

2.    委托者声明一个delegate;

3.    委托者调用delegate内的方法(method);

4.    被委托者设置delegate,以便被委托者调用;

5.    被委托者实现Delegate 所定义的方法。

接下来,我们来一步一步实现:

1.1    第一步: 创建一个delegate
在 .h 文件中, 通过 @protocol 创建一个 delegate: @protocol CalculatorProgramsTableViewControllerDelegate @optional - (void)calculatorProgramsTableViewController: (CalculatorPorgramTableViewController *)sender choseProgram:(id)program; @end 代码解释: @protocol CalculatorProgramsTableViewControllerDelegate 用来创建一个delegate。 这个delegate 中有一个方法: (void)calculatorProgramsTableViewController @optional 表明,这个方法是不要求一定实现,是可选的。 小贴士: 这里需明确一个概念, 虽然通过@protocol 定义了一个delegate,但不能说, delegate 就是protocol。 前面提到过,delegate是一种架构设计模式。 在iOS中,它是通过@protocol 来实现的。 1.2 第二步: 委托者声明一个delegate 在TableView 的 .h 文件中 (CalculatorProgramsTableViewController.h), 将之前创建的delegate 通过@property 进行声明。 代码如下: @interface CalculatorProgramsTableViewController : UITableViewController ... // Define a property delegate @property (nonatomic, weak) id<CalculatorProgramsTableViewControlerDelegate> delegate; ... @end 添加这几行代码后 , TableView 便拥有了Delegate。 有了Delegate, TableView就可以发消息了。 仅仅是可以发消息了,但还没有发。 下一步,Tableview 开始发送消息。 1.3 第三步:委托者调用delegate内的方法 我们的目标是: 当在TableView 上选择不同的函数时, TableView 将这个所选定的函数,告知绘制函数图形的GraphicView。 这一步,TableView 通过调用delegate的方法,发送消息。代码实现如下: #progma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSeelectRowAtIndexPath:(NSIndexPath *)indexPath { id program = [self.programs objectAtIndex:indexPath.row]; [self.delegate calculatorProgramsTableViewController:self choseProgram:porgram]; } 代码解释: 注意到 高亮部分的 self.delegate 了吧。 UITableView 就是通过这个之前定义的delegate 发送消息的。具体做法是: UITableViewController 调用delegate 中所定义的函数。通过这个函数的调用, 实现了消息的发送。但发到哪里去了,还不得而知。这是因为, self.delegate 还没赋值呢。 接下来,要做的是: 将 self.delegate 设置为GraphicView。 1.4 被委托者设置delegate,以便被委托者调用; 前面谈到, UITableViewController 中的self.delegate 还没有赋值。既然TableView 想把值传给Graphicview, 那就应该在calculatorGraphViewController.m 文件中设置delegate。 也就是说,让Graphicview 成为Tableview的delegate。 代码如下: @implementation CalculatorGraphViewController ... - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"Show Favorite Graphics"]) { NSArray * programs = [[NSUserDefaults standardUserDefaults] objectForKey:FAVORITES_KEY]; [segue.destinationViewController setPrograms:programs]; [segue.destinationViewController setDelegate:self]; // set delegate } } 代码解释: 但点击Graphicview 右上角的button 时, 会弹出一个Tableview。同时,在这段代码的最后一行,将CalculatorGraphViewController 设置为Tableview 的delegate。 通过这个设置, Tableview便可以调用Graphicview 所遵循的delegate 的的方法。 Delegate 的这个方法还没实现呢, 赶紧实现它吧。 1.5 被委托者实现Delegate 所定义的方法。 还记得那个神秘的 <> 吧。 通过以下代码,让GraphicViewController 来遵循这个delegate。 // .h to implement the protocol @interface CalculatorGraphViewController :NSObject <CalculatorProgramsTableViewControllerDelegate> ... @end 这是delegate使用的最后一步了, 我们在segue的controller 文件中,实现这个protocol所定义的方法。代码如下: // implement delegate method - (void)calculatorProgramsTableViewController:(CalculatorProgramsTableViewController *)sender chooseProgram:(id)program { self.calculatorProgram = program; } 1.6 小结
通过以上delegate 五部曲的演示,我们对delegate的机制,清楚些了吧。 Delegate 实现了不同视图之间的数据交互。 Delegate 属于事件驱动的范畴。只有当某一事件触发时,delegate 才被调用。 在Cocoa 框架中, 虽然数据存储和访问的方式有多种, 但delegate 所独有的数据交互模式是无可替代的。 注:以上来自斯坦福iOS 教学。 这是一个经典的 delegate 应用案例。 -----------------------

  

iOS 之美:iOS Delegate 使用五步曲的更多相关文章

  1. C语言程序设计入门学习五步曲(转发)

    笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的 ...

  2. 工作流学习——Activiti流程变量五步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46648139 ***************************************** ...

  3. Activiti流程变量五步曲 ——by fightingKing

    http://blog.csdn.net/zwk626542417/article/details/46648139 一.前言 上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这 ...

  4. 工作流学习——Activiti流程变量五步曲

    一.前言 上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这篇文章来介绍activiti中的流程变量. 二.正文 流程变量与我们寻常理解的变量是一样的,仅仅只是是用在了我们act ...

  5. iOS 11开发教程(十五)iOS11应用视图的位置和大小

    iOS 11开发教程(十五)iOS11应用视图的位置和大小 当一个视图使用拖动的方式添加到主视图后,它的位置和大小可以使用拖动的方式进行设置,也可以使用尺寸检查器面板中的内容进行设置,如图1.52所示 ...

  6. IOS开发使用委托delegate在不同窗口之间传递数据

    IOS开发使用委托delegate在不同窗口之间传递数据是本文要介绍的内容,主要是来讲解如何使用委托delegate在不同窗口之间传递数据,具体内容来看详细内容.在IOS开发里两个UIView窗口之间 ...

  7. iOS tableview的常用delegate和dataSource执行顺序

    在这次项目中遇到了一个特别奇葩的问题:表视图创建的cell在7以上的系统能正常运行显示,在模拟器上就不能正常实现......为解决这个问题,纠结了好久...... 对在7系统上不显示的猜测: 用mas ...

  8. IOS 动画专题 --iOS核心动画

    iOS开发系列--让你的应用“动”起来 --iOS核心动画 概览 通过核心动画创建基础动画.关键帧动画.动画组.转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等.在今天的文章里您可以看 ...

  9. iOS面试必备-iOS基础知识

    近期为准备找工作面试,在网络上搜集了这些题,以备面试之用. 插一条广告:本人求职,2016级应届毕业生,有开发经验.可独立开发,低薪求职.QQ:895193543 1.简述OC中内存管理机制. 答:内 ...

随机推荐

  1. MVC神韵---你想在哪解脱!(十六)

    MVC验证属性自动验证原理 也许有人会问,既然我们没有在C与V追加任何显示错误信息提示的代码,那么控制器或视图内部是如何生成这些显示错误信息提示的画面的.让我们揭开这么谜底吧!当在Movie类中追加了 ...

  2. ECSHOP数据表结构完整仔细说明教程

    From:http://www.ecshop119.com/ecshopjc-868.html s_account_log //用户账目日志表 字段 类型 Null 默认 注释 log_id medi ...

  3. Klist

    显示当前缓存的 Kerberos 票证的列表. 有关如何使用此命令的示例 语法 klist [-<LogonId.HighPart> lh] [-li <LogonId.LowPar ...

  4. jsp页面用el表达式获取枚举的code

    jsp页面用el表达式获取枚举的code <c:set var="D_BUSINESS" value="<%=DeptEnum.D_BUSINESS%> ...

  5. hdu 5569 matrix dp

    matrix Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5569 D ...

  6. 图的深度优先搜索算法DFS

    1.问题描写叙述与理解 深度优先搜索(Depth First Search.DFS)所遵循的策略.如同其名称所云.是在图中尽可能"更深"地进行搜索. 在深度优先搜索中,对最新发现的 ...

  7. 详谈 php定时器

    以前对se特别感兴趣,但是自己又不会java,lucene等搜索引擎开发工具,于是不断挖掘php的功效. 最后发现php也可以做抓取,并且原理很易:直接获取页面源文件,然后通过正则或字符串的参照截取来 ...

  8. ConfigurationManager.GetSection()方法的使用

    GetSection方法读取的是configSections节点,这个节点在web.config配置文件中,它比较特殊,必须放置于首节点,也就是说,在它之前不能有其它类型的节点.configSecti ...

  9. ASCII与UNICODE的区别

    1.ASCII的特点 ASCII 是用来表示英文字符的一种编码规范.每个ASCII字符占用1 个字节,因此,ASCII 编码可以表示的最大字符数是255(00H—FFH).这对于英文而言,是没有问题的 ...

  10. android:layout_weight总有你不知道的用法.

    都知道weight是权重的意思. 在布局中起到非常重要的作用. 但是这玩意不能嵌套使用, 而且只能使用在LinearLayout中. 下面说说它的几种用法(以下例子全为横排 注意android:lay ...