在OC基础(十一)中我们讨论了类别和非正式协议的奇异之处。在使用非正式协议时。能够仅仅实现你想要获得响应的方法。也不必在对象中声明不论什么内容来表示该对象可用作托付对象。

全部这些任务能够用最少的代码完毕。

以下来学习正式协议。

1. 正式协议

     与非正式协议一样。正式协议包括了方法和属性的有名称列表。

但与非正式协议不同的是,正式协议须要显示地採用。採用(adopt)协议的办法是在类的@interface声明中列出协议的名称。採用协议后,你的类就要遵守该协议。採用协议就意味着你承诺实现该协议的全部方法。否则,编译器会生成警告来提醒你。

1.1 声明协议

声明一个协议的方法很easy:
@protocol myProtocol <NSObject>
@required
-(void)protocolMethodA:(NSString *)string;
@optional
-(void)protocolMethodB:(NSString *)string;
@end

说明:
(1)第一行是声明这个协议的名字为myProtocol。尖括号里的NSObject本身也是一个协议,当中定义了非常多主要的协议函数。比方performSelector。isKindOfClass,respondsToSelector,conformsToProtocol,retain,release等。
(2)协议接口分为required和optional两类。required顾名思义是说遵守这个协议的那个类“必需要”实现的接口,而optional则是能够实现也能够不实现的。协议接口的定义和普通的函数定义是一样的。

(3)最后一行@end表示协议定义结束。这个协议的定义一般是在.h文件里。


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

@interface myClass <myProtocol>
@intrerface myClass : NSObject <myProtocol>
@interface myClass : NSObject <myProtocol, NSCoding>
说明:
上面各自是三种不同的情况。编译的时候编译器会自己主动检查myClass是否实现了myProtocol中的必要的(@required)接口。假设没有实现则会发出一个警告信息。另外须要注意的是,假设有继承自myClass的子类,这些子类也是会自己主动遵循myClass所遵循的协议的。并且也能够重载这些接口。


2.为什么要使用正式协议

苹果的官方文档指出三个原因:

  • 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的控制。


3.关于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的协议吧

OC基础回想(十二)协议的更多相关文章

  1. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

  2. Java 多线程基础(十二)生产者与消费者

    Java 多线程基础(十二)生产者与消费者 一.生产者与消费者模型 生产者与消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”.“消费者”.“仓库”和“产品”.他们之间的关系如下: ①.生 ...

  3. Python3基础(十二) 学习总结·附PDF

    Python是一门强大的解释型.面向对象的高级程序设计语言,它优雅.简单.可移植.易扩展,可用于桌面应用.系统编程.数据库编程.网络编程.web开发.图像处理.人工智能.数学应用.文本处理等等. 在学 ...

  4. OC基础--分类(category) 和 协议(protocol)

    OC 中的category分类文件相当于 C#中的部分类:OC 中的protocol协议文件(本质是头文件)相当于 C#中的接口.今天就简单说明一下OC中的这两个文件. 由于视频中的Xcode版本低, ...

  5. Android学习之基础知识十二 — 第一讲:网络技术的使用

    这一节主要讲如何在手机端使用HTTP协议和服务器端进行网络交互,并对服务器返回的数据进行解析,这也是Android中最常用的网络技术. 一.WebView的用法 有时候我们可能会碰到比较特殊的需求,比 ...

  6. IOS基础之 (十二) 类的扩展

    对OC类的扩展总结如下,共有4个: 1.子类 subClass 作用:可以使用类的继承来增添父类的变量和方法. 写法:在.h文件中 @interface Student : Person 2.分类 C ...

  7. Java基础(十二):包(package)

    一.Java 包(package): 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间.包的作用: 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹 ...

  8. Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式

    一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...

  9. ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

随机推荐

  1. 【百度之星】-IP聚合

    问题描述: Problem Description 当今世界,网络已经无处不在了,小度熊由于犯了错误,当上了度度公司的网络管理员,他手上有大量的 IP列表,小度熊想知道在某个固定的子网掩码下,有多少个 ...

  2. mysql索引的操作

    一.创建和查看普通索引 这是最基本的索引类型,而且它没有唯一性之类的限制 1.创建表时创建普通索引 CREATE TABLE table_name( 属性名 数据类型, ... 属性名 数据类型, I ...

  3. EF在应用程序配置文件中找不到名为“XXX”的连接字符串。

    现象: 在配置EF的时候需要如题所述的问题,仔细检查了在EF实体模型对应程序集下的APP.Config文件中的ConnectionString配置项有了XXX项的数据库字符串的配置: <conn ...

  4. java heap 异常

    近期,项目每运行一周之后就会堆异常, java.lang.OutOfMemoryError: Java heap space,导致应用中断. 解决办法:将堆内存修改大一点. 从性能优化工具中可以看到修 ...

  5. eclipse整合maven下载jar包速度慢问题解决

    引用:http://blog.csdn.net/u010154380/article/details/70339538 开发过程中在pom.xml中添加pom的时候,默认是需要从中央仓库中下载,但是下 ...

  6. Alpha Edition [ Group 1 ]

    Deltafish Alpha Edition 一.博客归档(记录人:娄雨禛) 小组会议 DeltaFish 校园物资共享平台 第一次小组会议 DeltaFish 校园物资共享平台 第二次小组会议 D ...

  7. Spring的核心机制依赖注入

    原文地址:http://developer.51cto.com/art/200610/33311.htm 本文主要讲解依赖注入(设值注入.构造注入),作用是可以使Spring将各层的对象以松耦合的方式 ...

  8. Angular——内置指令

    内置指令 ng-app 指定应用根元素,至少有一个元素指定了此属性. ng-controller 指定控制器 ng-show控制元素是否显示,true显示.false不显示 ng-hide控制元素是否 ...

  9. JS——缓动框架的问题

    1.opacity问题:IE678支持filter: alpha(opacity=50)取值1-100:小数位容易精度丢失,所i有统一json字符串设置为百进制,赋值时除以100 2.zIndex问题 ...

  10. JS——select标签

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...