惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
B
Blog
The GitHub Blog
The GitHub Blog
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
月光博客
月光博客
人人都是产品经理
人人都是产品经理
IT之家
IT之家
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
C
Check Point Blog
罗磊的独立博客

博客园 - 沙加

前端设计模式之 MPVC Part 3 前端设计模式之 MPVC Part 2 前端设计模式之 MPVC Part 1 App Engine 缓存与数据一致性 常用跨浏览器效果 同步请求真的有那么恐怖? Google Closure 的单元测试纪要 双飞翼布局的选区问题 一个 JS 面试题目 HTML 5 之旅 part 1 - 无头苍蝇 bind, delegate, live 三者的区别 Objective-C 学习笔记 - part 12 - 多线程 Objective-C 学习笔记 - part 11 - 错误处理 Objective-C 学习笔记 - part 10 - 选择器 Objective-C 学习笔记 - part 9 - 静态标记的类型 Objective-C 学习笔记 - part 8 - 快速枚举 Objective-C 学习笔记 - part 7 - 相关引用 Objective-C 学习笔记 - part 6 - 类别与扩展 Objective-C 学习笔记 - part 5 - 申明属性
Objective-C 学习笔记 - part 4 - 协议
沙加 · 2011-08-14 · via 博客园 - 沙加

**以下内容中 interface 指代传统意义上的接口, 而@interface 指代 Objective-C 中的类型规范概念,以免混乱。

看到这一章,有点奇怪,其实只要将 protocal 当作 C# 里面的接口来认识就好了。

因为 Objective-C 给每个 Class 都分配了一个 @interface ,因此用这人概念来表达 interface 的意思。

抽象出接口的目的:

1. 相似方法组的实现有共同的规范。
2. 让“接口”独立于类。
3. 封装没有继承关系的类的共性。

if ( [assistant respondsToSelector:@selector(helpOut:)] ) {
    [assistant helpOut:self];
    return YES;
}
return NO;

上面的代码是不是可以认为使用”反射“确定了一个对象是否支持一个方法调用。

但是 protocal 比 interface 强大的地方在于,它是可以跨应用程序的,这也是之所以叫它 protocal 的原因。

事实上,将“方法调用”都转换为消息传递本身就是弱化了应用程序域的概念,让多个程序可以无缝地工作在一起,在这一点上苹果确实是很高明的。

匿名类也可以利用 protocal 来与外界沟通而无需定义与之对应的 @interface。

如何申明一个 protocal:
@protocol ProtocolName
method declarations
@end

需要注意,协议不象类名称一样全局可见,它只存于作用的命名空间中。

协议用的方法可以申明为 option 方式(可选/非强制方式)

非正式的协议使用 @interface 来申明,如:
@interface NSObject ( MyXMLSupport )
- initFromXMLRepresentation:(NSXMLElement *)XMLElement;
- (NSXMLElement *)XMLRepresentation;
@end

与类对应的 @interface 不一样的是,非正式协议没有对应的实现文件,即只有一个空的协议在那里,可以认为它是用来标定一类有相似行为的类的分组方法。

非正式协议没有编译时的类型检查,如果需要类型检查,应该使用正式协议。

非正式协议常用于所有方法都是可选时的情形,但对于 OS X > 10.5 最好使用正式协议。

关于协议对象:

正式协议是一种特殊的数据类型:它闪是 Protocal 的实例而非一般对象是 Class 的实例。

运行时只初化有引用的 @protocal

关于采用一个协议;

不论正式或非正式协议都使用下面的语法来申明:
@interface ClassName : ItsSuperclass < protocol list >

使用多个协议的情况:
@interface Formatter : NSObject < Formatting, Prettifying >

使用协议的类需要 include 协议所在的 .h 文件,并且协议中的方法不义定义在 类型自己的@interface 中,这样来避免重复。

一个类可以没有对应的 @interface 而只有 protocal

可以使用下面的测试方法来检查一个对象是否遵守某个 protocal:
if ( ! [receiver conformsToProtocol:@protocol(MyXMLSupport)]  )

如果只需要检查一个特定方法的话,尽量使用 respondsToSelector: test 从则避免检测 protocal 中的所有方法。

协议可以继承

由于协议可以互相引用, 因此在某些情况下不需要 import 协议所在的文件,而只需要象这样:
@protocol B;
@protocol A
- foo:(id <B>)anObject;
@end