Objective-C 协议(protocol)
协议(protocol)是Objective-c中一个非常重要的语言特性,从概念上讲,非常类似于JAVA中接口. 一个协议其实就是一系列有关联的方法的集合(为方便后面叙述,我们把这个协议命名为myProtocol)。协议中的方法并不是由协议本身去实现,相反而是由遵循这个协议的其他类来实现。换句话说,协议myProtocol只是完成对协议函数的声明而并不管这些协议函数的具体实现。
声明一个协议的语法非常简单:
- @protocol myProtocol <NSObject>
- @required
- -(void) protocolNameA:(NSString*)string;
- @optional
- -(void) protocolNameB:(NSString*)string;
- @end
第一行是声明这个协议的名字为myProtocol。尖括号中的NSObject本身也是一个协议,其中定义了很多基本的协议函数,比如performSelector,isKindOfClass,respondsToSelector,conformsToProtocol,retain,release等。
协议接口分为required和optional两类。required顾名思义是说遵守这个协议的那个类“必须要”实现的接口,而optional则是可以实现也可以不实现的。协议接口的定义和普通的函数定义是一样的。
最后一行@end表示协议定义结束。这个协议的定义通常是在.h文件中。
定义一个类遵循这个协议:
- @interface myClass <myProtocol>
- @interface myClass :NSObject<myProtocol>
- @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:
- id <myProtocol> delegate;
这样,在编译阶段我们就可以知道用delegate所发送的消息是不是在它所遵循的myProtocol中的消息。好了, 到这里笔者钻起了牛角尖,我把id后面的 <myProtocol>删掉,然后用delegate发送一个并不存在于myProtocol中的消息,结果编译器还是给了“Instance method 'xxxx:' not found......”的警告信息。更奇怪的是,当发送一个存在于myProtocol中的消息时,编译器竟然没有这样的警告信息。这两个测试并不能说明之前的解释是错误的,姑且认为id<myProtocol> delegate这种写法是为了便于知道这个delegate遵循了myProtocol的协议吧。
Objective-C 协议(protocol)的更多相关文章
- iOS阶段学习第19天笔记(协议-Protocol)
iOS学习(OC语言)知识点整理 一.关于协议(Protocol)的介绍 1)概念:协议指多个对象之间协商的一个接口对象,协议提供了一些方法用在协议的实现者和代理者 之间通讯的一种方式 2) ...
- OC基础--分类(category) 和 协议(protocol)
OC 中的category分类文件相当于 C#中的部分类:OC 中的protocol协议文件(本质是头文件)相当于 C#中的接口.今天就简单说明一下OC中的这两个文件. 由于视频中的Xcode版本低, ...
- 协议Protocol
1.协议:是一组声明方法的集合,不能声明成员变量,作用类似于接口. 遵守此协议的类就相当于拥有了这个协议的所有方法的声明,如果父类遵守了某个协议,子类也遵守了这个协议. ...
- 浅谈iOS开发的协议(protocol)和代理(delegate)
协议和代理对于一个新手来说确实不讨好理解,也有很多的iOS开发的老手对此是懂非懂的.网上的很多博文只是讲了怎么使用,并没有说的很明白.下面我谈一下我的理解. 1.你要先搞明白,协议和代理为什么会出现, ...
- 关于ios object-c 类别-分类 category 的静态方法与私有变量,协议 protocol
关于ios object-c 类别-分类 category 的静态方法与私有变量,协议 protocol 2014-02-18 19:57 315人阅读 评论(0) 收藏 举报 1.category, ...
- Objective-C中的协议(Protocol)和类别(Category)
1.什么是协议? 2.协议与类别的声明和使用 1.什么是协议? 在Objective-C中,不支持多继承,即不允许一个类有多个父类,但是OC提供了类似的实现方法,也就是协议.协议有点类似于Java里的 ...
- Objective-C 中的协议(@protocol)和接口(@interface)的区别
Objective-C 中的协议(@protocol),依照我的理解,就是C#, Java, Pascal等语言中的接口(Interface).协议本身不实现任何方法,只是声明方法,使用协议的类必须实 ...
- Objective-C:继承、分类(Category、extension)、协议(protocol),个人理解,仅供参考
总结:继承.分类(Category.extension).协议(protocol) 一.继承: (1)特点: 继承多用于一般父类中的方法功能比较齐全,子类从父类继承过来使用,可以省略很多重复的代码 ...
- Objective-C:协议protocol
六.协议(protocol) 关键字:@optional.@required (1)是一个类共享的一个方法列表 (2)它声明了一系列的方法而不进行实现 (3)遵从某个协议,就是需要实现协议中的方法 ( ...
- 协议(Protocol)与委托代理(Delegate)
协议(Protocol)的作用: 1. 规范接口,用来定义一套公用的接口: 2. 约束或筛选对象. 代理(Delegate): 它本身是一种设计模式,委托一个对象<遵守协议>去做某件事情, ...
随机推荐
- 【C语言】01-第一个c程序代码分析
创建了一个C程序,接下来分析一下里面的代码. 项目结构如下: 一.代码分析 打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: 1 #i ...
- JavaScript--面向对象与原型(15)
// ECMAScript有两种开发模式:1.函数式(过程化);2.面向对象(OOP); 一 创建对象 1.普通的创建对象 1 // 创建一个对象,然后给这个对象新的属性和方法; 2 var box ...
- 利用js来实现一些常用的算法
示例代码中的arr指的是给出的数组,s指的是数组的起始坐标0,end指的是数组的最后一个坐标arr.length-1,n指的是要查找的数字 查找某个值: 1.线性法 function findInAr ...
- 【wenqi】重置Centos 7 Root密码
重置Centos 7 Root密码的方式和Centos 6完全不同.下面展示一下到底如何操作. 1 - 在启动grub菜单,选择编辑选项启动 2 - 按键盘e键,来进入编辑界面 3 - 找到Linux ...
- c#学习汇总-----------------多态
刚开通了博客园的博客,原因是我的师兄和前辈们在这里写的一些学习笔记让我受益匪浅,所以决定从今天起用这个平台来记录我的点滴学习心得.我喜欢GIS二次开发,以后应该也不会脱离于此,对于编程我积累的知识太零 ...
- WaitForSingleObject用法
对应函数 编辑 VC声明 DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); 参数 编辑 hHandle[in]对 ...
- 文件存储之-内存文件系统tmpfs
前言 我们都知道,对于单台服务器来说,除了 CPU ,内存就是我们存储数据最快的设备.如果可以把数据直接存储在内存中,对于性能的提升就不言而喻了.那么我们先来讲讲如何使用内存来存储文件. 首先,我们先 ...
- L011-oldboy-mysql-dba-lesson11
L011-oldboy-mysql-dba-lesson11 [root@ab01 ~]# mysqladmin -i 1 -r status #mysqladmin监控的命令 Uptime: ...
- 几种placeholder替换项目参数的方法比较
引言:(引自:http://openwebx.org/docs/autoconfig.html) 在一个应用中,我们总是会遇到一些参数,例如: 数据库服务器IP地址.端口.用户名: 用来保存上传资料的 ...
- 字符串转换成整型数 atoi()
题目说明: 1.设计函数: int atoi(const char *nptr); 2.功能:把字符串转换成整型数,atoi()会扫描参数nptr字符串,如果第一个非空格字符存在, 是数字或者正负号则 ...