为什么iPhone SDK会为某些代表使用类别而不是协议?

时间:2009-05-22 22:54:00

标签: iphone objective-c delegates protocols categories

我的理解是协议就像其他语言中的接口 - 它们声明了预期的方法 - 而类别允许您向现有类型添加新方法(甚至可能是您不拥有的类型。)

为什么iPhone SDK有时会使用类别来声明委托类型?通常我希望所有代表都是键入的id< MyDelegateProtocol>但是有许多例子并非如此。

例如,请参阅NSURLConnection。它的委托类型为“id”,而'contract'在NSObject(NSURLConnectionDelegate)上被声明为一个类别。

那么:在这些情况下使用类别的动机是什么?

3 个答案:

答案 0 :(得分:13)

Objective-C 2.0引入了@optional协议指令,允许您声明某些协议方法是可选的。在Obj-C 2.0之前,类别用于允许可选的委托方法(特别是NSObject上的类别,称为非正式协议)。

我的猜测是iPhone SDK中的大部分类别代替协议使用都是等效的Mac类的延续。例如,Mac和iPhone SDK中都存在NSURLConnection,因此可能会共享代码。由于Apple还没有通过改变所有的Mac类来使用正式协议,因此我们有点不一致。

答案 1 :(得分:4)

在使用OS X 10.5推出的Objective-C和名为“Objective-C 2.0”的iPhone SDK的修订之前,人们只能通过使用类别来制作可选协议。在Objective-C 2.0中,协议中添加了一个新的@optional关键字,用于标记哪些方法是可选的(其余部分是隐式需要的)。

所以我认为你所看到的是@optional关键字前几天的轻微拖延。

编辑:回答原始问题中出现的后续行动:在非正式协议上使用NSObject / id类别的动机部分是为了记录和分组对象在其数据源(或委托)中可以调用的方法或者其他方面,以及在较小程度上避免编译器警告您正在调用编译器不知道的方法将出现在接收调用的对象中。想象一下,实现调用这些数据源方法的类 - 你可能想要使用[obj respondsToSelector:@selector(my:datasource:method :)]检查方法是否存在,只要你有兴趣调用我的:datasource:方法:对象obj的方法。

答案 2 :(得分:1)

这是遗留来自objective-c 1.0,它没有“可选的协议方法”。