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

为什么iPhone SDK对某些代表使用类别而不是协议?,iphone,objective-c,delegates,protocols,categories,Iphone,Objective C,Delegates,Protocols,Categories,我的理解是,协议类似于其他语言中的接口——它们声明预期的方法——而类别允许您向现有类型(甚至可能是您不拥有的类型)添加新方法 那么,为什么iPhone SDK有时会使用类别来声明委托类型呢?通常情况下,我希望所有委托都是键入id的,但在许多示例中,情况并非如此 例如,请参见NSURLConnection。其委托类型为“id”,并且“contract”在NSObject(NSURLConnectionLegate)上声明为一个类别 那么:在这些情况下使用类别的动机是什么呢?Objective-C2

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

那么,为什么iPhone SDK有时会使用类别来声明委托类型呢?通常情况下,我希望所有委托都是键入id的,但在许多示例中,情况并非如此

例如,请参见NSURLConnection。其委托类型为“id”,并且“contract”在NSObject(NSURLConnectionLegate)上声明为一个类别


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

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


我的猜测是,iphonesdk中使用的大部分类别(而不是协议)都是等效Mac类的遗留。例如,
NSURLConnection
存在于Mac和iPhone SDK中,因此代码可能是共享的。由于苹果尚未将所有Mac类更改为使用正式协议,因此我们有点不一致。

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

因此,我认为您看到的是@optional关键字之前几天的轻微延迟


编辑:回答原始问题中出现的后续问题:将NSObject/id上的类别用于非正式协议的动机部分是记录和分组对象在其数据源(或委托或其他)中可能调用的方法,并在较小程度上避免编译器警告,即您正在调用编译器不知道将出现在接收调用的对象中的方法。假设您是实现调用这些数据源方法的类的人——您可能希望在有兴趣调用对象obj上的my:datasource:method:method时,使用[obj respondsToSelector:@selector(my:datasource:method:)]检查该方法是否存在。

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

这是我的猜测,但我不确定。谢谢不过,预计很快就会看到协议的变化。现在允许使用可选的协议方法,使用它们将相当多地清理代码,并消除许多现在不必要的类别。(它们很酷,但我认为让委托实现协议比在运行时在NSObject上附加方法更干净,无论是从概念上还是从运行时的角度看。)