zoukankan      html  css  js  c++  java
  • IOS_协议与委托

    协议(protocol),就是使用了这个协议后就要按照这个协议来办事,协议要求实现的方法就一定要实现相当于定义一个人的能力标准。

    委托(delegate),顾名思义就是委托别人办事,就是当 一件事情发生后,自己不处理,让别人来处理。当然那个人也需要满足做那个事情的能力才行(实现协议protocol)。

    举个浅显的例子:

               我上班的工作主要内容包括 (1)写代码(2)写文档(3)测试程序(4)接电话(5)会见客户

    (1)(2)我自己全权负责,但是后面(3)(4)(5)我不想或者不方便自己做,所以我想找个助手(delegate)帮我做这些事,于是我定了一个招聘要求(Protocol),里写明我的助手需要会做(3)(4)(5)这三件事。很快,我招到一个助手。

            即:我.delegate = 助手;

    于是以后每当我遇到需要测试程序或者接电话的活,我就把他转交给助手(delegate)去处理,助手处理完后如果有处理结果(返回值)助手会告诉我,也许我会拿来用。如果不需要或者没有结果,我就接着做下面的事。。

    protocol和java里interface的概念类似,是Objective-C语法的一部分。

    定义protocol如下

    C代码  收藏代码
    1. @protocol ClassADelegate  
    2.    
    3. - (void)methodA;  
    4. - (void)methodB;  
    5.    
    6. @end  

     

    那么就是定义了一组函数,这组函数放在一起叫作一个protocol,也就是协议。

    函数是需要被实现的,所以如果对于class如下

    C代码  收藏代码
    1. @interface ClassB <ClassADelegate> {  
    2. }  
    3. @end  

     

    就叫作ClassB conform to protocol ClassADelegate,也就是说ClassB实现了这个协议,

    也就是实现了这一组函数。

    有了上面这个头文件,我们就可以放心作调用

    C代码  收藏代码
    1. ClassB *b = [[ClassB alloc] init];  
    2. [b methodA];  
    3. [b methodB];  

     

    而不用担心出现unrecognized selector sent to instance这种错误了。

    所以protocol就是一组函数定义,是从类声明中剥离出来的一组定义。

    C代码  收藏代码
    1. id<ClassADelegate> b = ...;  
    2. [b methodA];  

     

    这种用法也常见,b是一个id类型,它知道ClassADelegate这组函数的实现。

    那么delegate是什么?其实和protocol没有关系。Delegate本身应该称为一种设计模式。

    是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。

    比如ClassC

    C代码  收藏代码
    1. @interface ClassC {  
    2.     id delegate;  
    3. }  
    4. @end  

     

    那么ClassC的实现(.m文件)里就可以用delegate这个变量了。

    当然这里完全可以用其它名字而不是delegate。

    我们也可以这样写

    C代码  收藏代码
    1. @interface ClassC {  
    2.     ClassB *delegate;  
    3. }  
    4. @end  

     

    这样我们知道了delegate是一个ClassB,它就可以提供ClassB里的方法。

    可以把一部分ClassC里的工作放在ClassB里去实现。

    这样的写法看起来是不是有点奇怪?或者应该写成这样?

    C代码  收藏代码
    1. @interface ClassC {  
    2.     ClassB *classB;  
    3. }  
    4. @end  
    5. …  

     

    delegate没有了…

    所以说其实delegate只是一种模式,大家约定俗成,当把自己内部一部分实现暴露给另外一个类去做的时候,就叫实际做事的类为delegate。

    为什么会需要把内部实现提出来给另一个类做呢?

    最常见的目的就是为了在隐藏实现的前提下,提供一个自定义的机会。

    比如Apple提供的iOS SDK里就有众多的delegate,比如最常用的UITableView,

    我们没法知道Apple怎么重用UITableViewCell,怎么处理UITableView里Cell的增加、删减,因为我们没有源码。

    但是我们可以通过实现Delegate的方法来控制一个UITableView的一些行为。

    UITableViewDataSource其实和delegate是一样一样的,只是由于意义不同换了个名字罢了。

    protocol在此扮演了什么角色呢?

    protocol是一种语法,它提供了一个很方便的、实现delegate模式的机会。

    比如写UITableView的时候,Apple这么干

    UITableView.m

    C代码  收藏代码
    1. - (void)doSomething {  
    2.     [self blahblah];  
    3.    
    4.     [self.delegate guruguru];  
    5.    
    6.     [self blahblah];  
    7.  }  

     

    delegate是我们写的类,这个类如果可以被传给UITableView做为其delegate,那唯一要求,就是它实现了

    - (void)guruguru;

    这个方法。

    如果我们把这个方法定义在一个protocol里

    C代码  收藏代码
    1. @protocol XXXProtocol  
    2.    
    3. - (void)guruguru;  
    4.    
    5. @end  

     

    就说明了,UITableView需要的delegate是一个conform to XXXProtocol的类。

    这就正好是

    id<XXXProtocol>

    表达的意思。

    无论具体的类是什么,它还有其它什么方法,只要它conform to这个protocol,

    就说明它可以被传给UITableView,作为它的delegate。

    那么Apple为了让我们知道这个protocol是delegate需要conform的protocol,

    它就把XXXProtocol改成了UITableViewDelegate

    这样我们看到protocol的名字里有Delegate,就知道这个protocol里的函数是用来做自定义(Customization)的了。

  • 相关阅读:
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherK
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher I
    pat 1065 A+B and C (64bit)(20 分)(大数, Java)
    pat 1069 The Black Hole of Numbers(20 分)
    pat 1077 Kuchiguse(20 分) (字典树)
    pat 1084 Broken Keyboard(20 分)
    pat 1092 To Buy or Not to Buy(20 分)
    pat 1046 Shortest Distance(20 分) (线段树)
    pat 1042 Shuffling Machine(20 分)
  • 原文地址:https://www.cnblogs.com/changjiang/p/2847317.html
Copyright © 2011-2022 走看看