9

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

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

例如,参见 NSURLConnection。它的委托类型为“id”,并且“合同”被声明为 NSObject (NSURLConnectionDelegate) 上的一个类别。

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

4

3 回答 3

13

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

我的猜测是,iPhone SDK 中使用的大多数类别而不是协议是对等 Mac 类的保留。例如,NSURLConnection存在于 Mac 和 iPhone SDK 中,因此代码可能是共享的。由于 Apple 尚未更改所有 Mac 类以使用正式协议,因此我们留下了一些不一致的地方。

于 2009-05-22T22:59:56.200 回答
4

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

因此,我认为您看到的是 @optional 关键字之前的早期版本的轻微保留。

编辑:回答原始问题中出现的后续问题:将 NSObject/id 上的类别用于非正式协议的动机部分是记录和分组对象可能在其数据源(或委托或其他)中调用的方法, 并在较小程度上避免编译器警告您正在调用编译器不知道的方法将出现在接收调用的对象中。想象一下自己是实现调用这些数据源方法的类的人——当你有兴趣调用 my :datasource:method: 对象 obj 上的方法。

于 2009-05-22T23:00:30.943 回答
1

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

于 2009-05-23T02:07:20.487 回答