通过委托与数据源协议进行对象间的通信

《Effective Objective-C 2.0》读书笔记

Posted by Japho on June 27, 2018

Objective-C不支持多继承,因此我们把某个类应该实现的一系列方法定义在协议里面。协议最常见的用途就是委托模式(delegate),“分类”(category),也是Objective-C的一种重要语言特性,利用分类机制,我们无需继承子类即可直接为当前类添加方法。

委托模式的主旨:

定义一套接口,某对象若想接受另一个对象的委托,则需遵从此接口。以便成为其“委托对象”。这里“另一个对象”则可以给其委托对象回传一些信息,也可以在发生相关事件时通知委托对象。

这个模式可将数据与业务逻辑解耦。视图中知应包含显示数据所需的逻辑代码,而不应决定要显示何种数据以及数据之间如何交互等问题。

delegate这个属性应该定义成weak,而非strong。因为两者之间必须为“费用有关系”。通常情况下,扮演delegate的对象也要持有本对象,直到对象用完之后才会被释放。假如这里声明的时候用的是strong,这里就会造成“循环引用”,对象无法被释放掉。所以delegate对象应该被声明为weak,或者unsafe_unretained,(区别在于weak可在相关对象销毁时自动清空设置成nil,不会造成野指针)。

实现委托对象的办法是声明某个类遵从委托协议,然后把协议中想要实现的那些方法在类里实现出来。委托协议一般来说都是可选的(optional),因为委托者未必关心其中的所有方法,这里需要注意,如果在委托对象上调用了可选方法,则必须提前使用类型信息查询方法来判断这个委托对象能否响应相关选择子。 例如

if ([_delegate respondsToSelecto: @selector(networkFetcher:didReceiveData:)])
{
[_delegate networkFetcher:self didReceiveData:data];
}

要点:

  • 委托模式为对象提供了一套接口,使其可由此将相关事件告知其他对象。
  • 将委托对象应该支持的接口定义成协议,在协议中把可能需要处理的事件定义成方法。
  • 当某对象要从另外一个对象中获取数据时,可以使用委托模式。这种模式下,该模式也叫做“数据源协议”。
  • 如果有必要,可实现含有段位的结构体,将委托对象是否能响应相关协议方法这一信息缓存至其中(delegate多次调用,后续检测多余,如果委托对象本身没有变化,不太可能会突然响应某个原来不能响应的选择子,这时可以考虑这种问题)。