通过协议提供匿名方法

2017/9/2 posted in  第四章 协议与分类

协议定义了一系列方法,遵从此协议的对象应该实现它们(如果这些方法不是可选的, 那么就必须实现)。于是,我们可以用协议把自己所写的API之中的实现细节隐藏起来,将返回的对象设计为遵从此协议的纯id类型。

这样的话,想要隐藏的类名就不会出现在API之中了。若是接口背后有多个不同的实现类,而你又不想指明具体使用哪个类,那么可以考虑用这个办法——因为有时候这些类可能会变,有时候它们又无法容纳于标准的类继承体系中,因而不能以某个公共基类来统一表示。

此概念经常称为“匿名对象"(anonymous object),这与其他语言中的“匿名对象”不同,在那些语言中,该词是指以内联形式所创建出来的无名类,而此词在Objective-C中则不是这个意思。

我们之前说的委托与数据源对象,就用到了这个方法。例如在定义“受委托者(delegate)”属性时:

@property {nonatomic, weak) id <EOCDelegate> delegate;

由于该属性的类型是id<EOCDelegate>,所以实际上任何类的对象都能充当这一属性, 即便该类不继承自NSObject也可以,只要遵循EOCDelegate协议就行。对于具备此属性的类来说,delegate就是“匿名的”(ammymous)。如有需要,可在运行期査出此对象所属的类型(参见第14条)。然而这样做不太好,因为指定属性类型时所写的那个EOCDelegate契约已经表明此对象的具体类型无关紧要了。

当然还有其它的用法,这里我们就不举例了。

要点

  • 协议可在某种程度上提供匿名类型。具体的对象类型可以淡化成遵从某协议的id类型,协议里规定了对象所应实现的方法。
  • 使用匿名对象来隐藏类型名称(或类名)。
  • 如果具体类型不重要,重要的是对象能够响应(定义在协议里的)特定方法,那么可使用匿名对象来表示。