协议(protocol)是Objective-c中一个很是重要的语言特性,从概念上讲,很是相似于JAVA中接口. 一个协议其实就是一系列有关联的方法的集合(为方便后面叙述,咱们把这个协议命名为myProtocol)。协议中的方法并非由协议自己去实现,相反而 是由遵循这个协议的其余类来实现。换句话说,协议myProtocol只是完成对协议函数的声明而并无论这些协议函数的具体实现。一般协议和delegate同时使用是一种很是好的设计模式。html
声明一个协议的语法很是简单:设计模式
第一行是声明这个协议的名字为myProtocol。尖括号中的NSObject自己也是一个协议,其中定义了不少基本的协议函数,好比 performSelector,isKindOfClass,respondsToSelector,conformsToProtocol,retain,release 等。app
协议接口分为required和optional两类。required顾名思义是说遵照这个协议的那个类“必需要”实现的接口,而optional则是能够实现也能够不实现的。协议接口的定义和普通的函数定义是同样的。框架
最后一行@end表示协议定义结束。这个协议的定义一般是在.h文件中。函数
定义一个类遵循这个协议:测试
上 面分别是三种不一样的状况。编译的时候编译器会自动检查myClass是否实现了myProtocol中的必要的(@required)接口。若是没有实现 则会发出一个警告信息。另外须要注意的是,若是有继承自myClass的子类,这些子类也是会自动遵循myClass所遵循的协议的,并且也能够重载这些 接口。ui
为何须要协议?spa
苹果的官方文档指出三个缘由:.net
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: