博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Objective-C 协议(protocol)
阅读量:7113 次
发布时间:2019-06-28

本文共 2228 字,大约阅读时间需要 7 分钟。

协议(protocol)是Objective-c中一个非常重要的语言特性,从概念上讲,非常类似于JAVA中接口. 一个协议其实就是一系列有关联的方法的集合(为方便后面叙述,我们把这个协议命名为myProtocol)。协议中的方法并不是由协议本身去实现,相反而是由遵循这个协议的其他类来实现。换句话说,协议myProtocol只是完成对协议函数的声明而并不管这些协议函数的具体实现。

声明一个协议的语法非常简单:

 

[cpp] 
 
  1. @protocol myProtocol <NSObject>  
  2. @required  
  3. -(void) protocolNameA:(NSString*)string;  
  4. @optional  
  5. -(void) protocolNameB:(NSString*)string;  
  6. @end  

 

 

第一行是声明这个协议的名字为myProtocol。尖括号中的NSObject本身也是一个协议,其中定义了很多基本的协议函数,比如performSelector,isKindOfClass,respondsToSelector,conformsToProtocol,retain,release等。

协议接口分为required和optional两类。required顾名思义是说遵守这个协议的那个类“必须要”实现的接口,而optional则是可以实现也可以不实现的。协议接口的定义和普通的函数定义是一样的。

最后一行@end表示协议定义结束。这个协议的定义通常是在.h文件中。

 

定义一个类遵循这个协议:

 

[cpp] 
 
  1. @interface myClass  <myProtocol>  
  2. @interface myClass :NSObject<myProtocol>  
  3. @interface myClass :NSObject<myProtocol, NSCoding>  

上面分别是三种不同的情况。编译的时候编译器会自动检查myClass是否实现了myProtocol中的必要的(@required)接口。如果没有实现则会发出一个警告信息。另外需要注意的是,如果有继承自myClass的子类,这些子类也是会自动遵循myClass所遵循的协议的,而且也可以重载这些接口。

 

 

为什么需要协议?

苹果的指出三个原因:

 

    • To declare methods that others are expected to implement

    • To declare the interface to an object while concealing its class

    • To capture similarities among classes that are not hierarchically related

       

      其实还有第四个很重要的原因,那就是减少继承类的复杂性。一个经典的例子就是iOS UI框架里面的UITableViewController类。假如没有“协议”功能,用户就必须选择用继承和重载接口的方法来实现复杂的UI控制以及其他事件的处理——这就对基类的设计提出了更大的挑战了。对于像这样一个table view,一个很好的实现方法就是采用协议,由协议里的接口来控制不同的数据源以及各种复杂的用户操作。UIKit中设计了两个很好的协议UITableViewDelegate,UITableViewDataSource来实现UITableViewController的控制。任何遵循这两个协议的类都可以实现对UITableView的控制。

       

      关于 id类型的运用:(不喜欢钻牛角尖的朋友,可以略过这一部分)

      id 类型在iOS中是一个通用类型,有点类似C语言的void*类型。编译器不能检查到定义为id类型的变量的实际类型,id类型的识别是发生在运行时阶段。但是我们可以用 id<protocol_name> obj;这样的语法形式在编译阶段就可以让编译器知道obj只可以发送protocol_name中的消息,如果所发送的消息不在protocol_name中,编译器会给一个警告信息“Instance method 'xxxx:' not found......”。这种情况多用于代理模式的实现,比如某一个类有一个delegate 的property:

       

      [cpp] 
       
      1. id <myProtocol> delegate;  
      这样,在编译阶段我们就可以知道用delegate所发送的消息是不是在它所遵循的myProtocol中的消息。好了, 到这里笔者钻起了牛角尖,我把id后面的 <myProtocol>删掉,然后用delegate发送一个并不存在于myProtocol中的消息,结果编译器还是给了“Instance method 'xxxx:' not found......”的警告信息。更奇怪的是,当发送一个存在于myProtocol中的消息时,编译器竟然没有这样的警告信息。这两个测试并不能说明之前的解释是错误的,姑且认为id<myProtocol> delegate这种写法是为了便于知道这个delegate遵循了myProtocol的协议吧。
如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/
你可能感兴趣的文章
周期性计划任务/权限/LDAP见解
查看>>
思科拓扑---rip协议应用
查看>>
python 高阶函数:返回函数
查看>>
OSI模型及IP分类---来自达内学员吴瑞课堂笔记
查看>>
<java基础>基本数据类型 <3>
查看>>
c# sendmessage control to scroll
查看>>
领域驱动设计,让程序员心中有码
查看>>
kvm 常用的一些操作
查看>>
移动端车牌识别的运用与未来
查看>>
“寒冬”再次来临,程序员如何避免被“人才优化”?
查看>>
Oracle技术之Index Merge与and_equal 的变迁
查看>>
oracle技术之索引结构小结
查看>>
win7 隐藏最近打开的文档
查看>>
haproxy 基本应用
查看>>
hive元数据存储
查看>>
centos 6.2安装bind 9.8.2 master、slave与自动修改后更新
查看>>
清maillog
查看>>
java——演示封装的思想
查看>>
【Windows server 2008】用户添加
查看>>
python 调试
查看>>