zoukankan      html  css  js  c++  java
  • 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 应用案例。
    
    -----------------------
    

      

  • 相关阅读:
    JUnit之持续集成(CI,Continuous Integration)
    Junit初级编码(二)探索JUnit核心
    《opencv学习》 之 特征检测与匹配
    opencv小问题大智慧
    opencv3.1+contrib的配置大总结(配置了两天,遇到问题无数)
    《图像处理实例》 之 透视变换
    《图像处理实例》 之 物体计数
    《图像处理实例》 之 操作规则的圆
    《电路学习第三天》 之 彩扩机项目设计
    《图像处理实例》 之 提取特殊背景的直线
  • 原文地址:https://www.cnblogs.com/killiancheung/p/4688335.html
Copyright © 2011-2022 走看看