2011-01-14 63 views
5

我正在研究一些关于非正式协议和真实协议的基础知识。令我困惑的是,Cocoa似乎在NSObject上使用了很多非正式的协议。这些非正式协议是NSObject的类别,它声明方法,但实际上并没有实现它们。在NSObject上使用非正式协议或使用可选方法的协议有什么区别?

据我所知,他们使用非正式协议(换句话说,NSObject上没有提供方法实现的类别)的唯一原因是在Xcode中给出一个自动完成提示。

一个示例是NSNibLoading.h中定义的-awakeFromNib方法,NSNibLoading.h是NSObject上的非正式协议。笔尖加载系统在运行时检查对象是否实现该方法。如果是这样,那么它会调用它。

但现在让我们想象一下,没有任何功能称为非正式协议。另一种具有完全相同效果的替代方案将是一个真正的@protocol声明,它声明了一个可选方法-awakeFromNib。 NSObject只会采用该协议,编译器会愉快地提供自动完成。

任何人都可以指出这两种策略之间的巨大差异吗?我没有看到非正式协议的重点,但真的很想这样做。

回答

7

两个巨大的差异:

  1. 编译时类型检查。使用可选方法的显式协议更清楚您可以实现哪些方法。无论是用它所符合的协议明确装饰类,Xcode都可以提供更精确的代码完成列表,包括您可以实现的内容。

  2. 它保持NSObject整洁。使用旧式非正式协议,所有可选的方法通常都会将默认实现添加到NSObject

自从Objective-C 2.0中的协议中引入可选方法以来,不再存在的问题的整洁解决方案的非正式协议。

1

为了使用一个协议,你必须导入它,并让你的编码对象符合它

TestViewController : UIViewController <MyAwesomeProtocol> 

为了要使用的类别,你不必做这样的事情,你可以简单地导入类(甚至在所有情况下都不需要)并使用对象(在我的情况下是一个UIViewController),就像你经常会这样,XCode会为你提供类的方法的自动完成。

我更喜欢协议的方式,它更加严格和可靠。类别往往会造成建设问题,说实话,有点奇怪(在大多数情况下并非全部)。

+0

什么样的建筑问题? – 2011-01-14 13:28:42

+0

在某些情况下,您可能会使用库的混合,或者甚至自己编译一个库,而这些类别往往会出现问题。目前我还没有一个明确的例子,但是我知道,由于类别的原因,我们的项目中的three20框架导致了这些类型的问题。不是一个大粉丝。 – Jake 2011-01-25 11:42:34

3

最大的区别在于@optional关键字是在几年前才推出的。对于新代码,非正式协议基本已过时。大部分框架都是非新代码。