协议定义了一些列方法, 遵从此协议的对象应该事实现他们(如果这些方法不是可选的,那么就必须实现),于是,我们可以用协议把自己缩写的 API 之中的实现细节隐藏起来, 将返回的对象设计为遵从此协议的纯 id 类型,这样的话,想要隐藏的类名就不会出现在 API 之中了, 若是接口背后有多个不同的实现类, 而你又不想指定使用那个类, 那么可以考虑用和这个方法--因为有时候这些类可能会变, 有时候它们又无法容纳与标准的类继承体系中, 因而不能以某个公共基类来同统一表示. 此概念经常称为'匿名对象', 这与其他语言中的'匿名对象'不同, 在其他语言中, 该词是指以内联形式所创建出来的无名类, 而此词在 OC 中则不是这个意思,例如,在定义'受委托者(delegate)'这个属性时,可以这样写: @property (nonatomic,weak) iddelegate; 由于该属性的类型是 id,所以实际上任何类的对象都能充当这一属性, 即便该类不继承自 NSObject 也可以, 只要遵循 EOCDelegate 协议就好, 对于具备此属性的类来说, delegate 就是'匿名的', 如有需要, 可以在运行期查出此对象所述的类型. 然而这样不太好, 因为指定属性类型时所写的 id 已经表明此对象的具体类型无关紧要了. NSDictionary 也能实际说明这一概念, 在字典中, 键的标准内存管理语义是'设置时拷贝', 而值的语义是'设置时保留', 因此, 在可变版本的字典中, 设置键值对所用的方法的签名是: - (void)setObject:(id)object forKey:(id)key 表示键的那个参数其类型为 id, 作为参数值的对象,它可以是任何类型的, 只要遵循从 NSCopying 协议就好, 这样的话, 就能向该对象发送拷贝消息了.
这个 key 参数可以视为匿名对象, 与 delegate 属性一样,字典也不关心 key 对象所属的具体类,而且它也不应该依赖于此, 字典对象只要能确定它可以给此实例发送拷贝消息就行了.
处理数据库连接的 程序库也用这个思路, 以匿名对象类表示从另一个库中所返回的对象,对于处理连接所用的那个类, 你也许不想交外人知道其名字, 因为不同的数据库可能要用不同的类来处理, 如果没有办法令其都继承同意基类, 那么久的返回 id 类型的东西, 不过我们可以把所有的数据库连接都具备的那些方法放到协议中, 令返回的对象遵循此协议,
总结: 协议可在某种程度上提供匿名类型, 具体的对象类型可以淡化成遵循某协议的 id 类型, 协议里规定了对象所应实现的方法.
使用匿名对象来隐藏类型名称
如果具体类型不重要, 重要的是对象能够响应(定义在协议里的)特定方法, 那么可使用匿名对象来表示.