iOS 之美:iOS Delegate 使用五步曲

在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 应用案例。

-----------------------

  

时间: 2024-10-19 02:33:27

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

从一名打工者蜕变成一名企业家的五步曲

无数打工者每天皆梦想能于某天开创自己的公司.其总觉得自己拥有着进入一个领域并打造出一个成功的事业所需的正确的技能或者正确的创业点子.但,这些人到现在都还是只是在脑袋里意淫着而已,他们并没有真正的付诸行动去开始追求他们的创业点子.这又是为何呢? 如果你有一个可以创业的点子但又没有真正放手去干,那是因为什么原因拖了你后腿呢? 对于很多有抱负的企业家来说,缺乏如何启动一个可以催生出一家公司的项目的蓝图,让他们举步维艰.大部分人甚至不知道如何举出第一步,剩下一部分人却又不确定这种职业生涯是否是他们自己想

Kali Linux渗透测试五步曲

Kali Linux的设计目的是渗透测试.不管渗透测试者的起点是白盒测试.黑盒测试,还是灰盒测试,在用Kali或其它工具进行渗透测试时,总要遵循一些步骤. 第一步:侦察阶段 在发动攻击之前,渗透测试者应当尽量多地了解目标环境和系统的特点.渗透测试者找到的目标信息越多,就越有更好的机会确认最容易和最快的成功方法.与白盒测试相比,黑盒测试要求进行更多的侦察,因为测试者并没有获得太多的数据.侦察服务可能包括调查目标的互联网足迹.监视资源.监视人员.过程等,扫描网络信息(如IP地址和系统类型),社会工程

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

笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的语法知识,而我们编写的程序或软件是要根据要解决问题的实际需要控制程序的流程,如果你没有深刻地理解C语言的语句的执行过程(或流程),你怎么会编写程序解决这些实际问题呢? 二.用C语言编程解决实际问题,所需要的不仅仅是C语言的编程知识,还需要相关的专业知识.例如,如果你不知道长方形的面积公式,即使C语言

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

一.前言 上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这篇文章来介绍activiti中的流程变量. 二.正文 流程变量与我们平常理解的变量是一样的,只不过是用在了我们activiti中,所以称为流程变量,流程变量在整个工作流扮演着很重要的角色. 例如,请假流程中有请假天数.请假原因等一些参数都是流程变量使用的范围,流程变量的作用域范围是只对应一个流程实例.也就是说各个流程实例的流程变量是不互相影响的.流程实例结束完成以后流程变量还保存在数据库中(存放在流程变量的历史表中

[FE] Chrome Extension 五步曲

1. Create the manifest.json Only three fields is needed. { "name": "Getting Started Example", "version": "1.0", "manifest_version": 2, "description": "xx" } 2. Add instruction (backgrou

iOS 协议delegate分六步

第一步:声明协议 在RootView.h中, @protocol 协议名 <基类> 方法 @end @protocol RootViewDelegate <NSObject> - (void)presentToViewController; @end 第二步:声明代理人 在RootView.h中 //必须是assign,为了防止两个对象之间的循环引用 @property (nonatomic, assign)id<RootViewDelegate>rootDelegat

iOS开发网络篇—文件下载(五&#183;下载功能的封装)

iOS开发网络篇—文件下载(五·下载功能的封装) 一.简单说明 在前面几篇文章介绍下载代码的基础上,此文分析对下载功能进行封装. 通过之前的代码,我们发现仅仅是下载一个文件就需要写很长的代码,那么如果要下载多个文件,就需要写多份代码.在这里,我们把下载一个文件的代码进行封装.控制器只需要知道,下载哪个文件,下载到哪个路径就可以了. 在对下载的功能进行封装后,添加一个文件下载器,一个文件下载器只下载一个文件,封装后如果要下载多个文件的话,那么只需要创建多个文件下载器对象就可以进行控制和下载了. 二

【iOS开发每日小笔记(五)】实测copy到底是个神马玩意

这篇文章是我的[iOS开发每日小笔记]系列中的一片,记录的是今天在开发工作中遇到的,可以用很短的文章或很小的demo演示解释出来的小心得小技巧.该分类的文章,内容涉及的知识点可能是很简单的.或是用很短代码片段就能实现的,但在我看来它们可能会给用户体验.代码效率得到一些提升,或是之前自己没有接触过的技术,很开心的学到了,放在这里得瑟一下.其实,90%的作用是帮助自己回顾.记忆.复习.如果看官觉得太easy,太碎片,则可以有两个选择:1,移步[iOS探究]分类,对那里的文章进行斧正:2,在本文的评论

SKProductsRequest ios 7不调用delegate

在iOS7中,内购只能在真机上才会调用 - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response协议方法 若是用模拟器,它回调用 - (void)request:(SKRequest *)request didFailWithError:(NSError *)error { DLog(@"error ====== %@", error);