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

Posted

技术标签:

【中文标题】为啥 iPhone SDK 对某些代表使用类别而不是协议?【英文标题】:Why does the iPhone SDK use categories, rather than protocols, for some delegates?为什么 iPhone SDK 对某些代表使用类别而不是协议? 【发布时间】:2009-05-22 22:53:59 【问题描述】:

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

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

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

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

这是我的猜测,但我不确定。谢谢! 不过,预计很快就会看到对协议的更改。现在允许使用可选的协议方法,使用它们将清理代码并摆脱许多现在不必要的类别。 (它们很酷,但不是在运行时在 NSObject 上添加方法,我认为让委托实现协议要干净得多,无论是从概念上还是从运行时的角度来看。)【参考方案2】:

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

所以我认为您所看到的与@optional 关键字之前的早期相比略有保留。

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

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于为啥 iPhone SDK 对某些代表使用类别而不是协议?的主要内容,如果未能解决你的问题,请参考以下文章

子类将继承父类所有的方法和属性吗?为啥?

为啥应用程序可以在 iPhone 上运行,而不是在 iPad 上运行?

从 iphone 应用程序拨打电话而不从 ios sdk4.0 退出

当我尝试使用 iPhone SDK 的 Finch 库播放声音时,为啥我的应用程序会崩溃?

iPhone SDK audioSession 问题

为啥 facebook sdk 会自动让我登录 iPhone 上安装的 facebook 应用程序?