常见的消息传递方法有5种
- 1、KVO
- 2、通知
- 3、delegation
- 4、block
- 5、target-action
KVO
KVO 是提供对象属性被改变时的通知的机制。KVO 的实现在 Foundation 中,很多基于 Foundation 的框架都依赖它
如果只对某个对象的值的改变感兴趣的话,就可以使用 KVO 消息传递。不过有一些前提:第一,接收者(接收对象改变的通知的对象)需要知道发送者 (值会改变的对象);第二,接收者需要知道发送者的生命周期,因为它需要在发送者被销毁前注销观察者身份。如果这两个要去符合的话,这个消息传递机制可以一对多(多个观察者可以注册观察同一个对象的变化)
通知
要在代码中的两个不相关的模块中传递消息时,通知机制是非常好的工具。通知机制广播消息,当消息内容丰富而且无需指望接收者一定要关注的话这一招特别有用。
通知可以用来发送任意消息,甚至可以包含一个 userInfo 字典。你也可以继承 NSNotification 写一个自己的通知类来自定义行为。通知的独特之处在于,发送者和接收者不需要相互知道对方,所以通知可以被用来在不同的相隔很远的模块之间传递消息。这就意味着这种消息传递是单向的,我们不能回复一个通知
委托 (Delegation)
Delegation
在苹果的框架中广泛存在。它让我们能自定义对象的行为,并收到一些触发的事件。要使用 delegation
模式的话,发送者需要知道接收者,但是反过来没有要求。因为发送者只需要知道接收者符合一定的协议,所以它们两者结合的很松。
因为 delegate
协议可以定义任何的方法,我们可以照着自己的需求来传递消息。可以用方法参数来传递消息内容,delegate 可以通过返回值的形式来给发送者作出回应。如果只要在相对接近的两个模块间传递消息,delgation
是很灵活很直接的消息传递机制。
过度使用 delegation
也会带来风险。如果两个对象结合得很紧密,任何其中一个对象都不能单独运转,那么就不需要用 delegate 协议了。这些情况下,对象已经知道各自的类型,可以直接交流。两个比较新的例子是 UICollectionViewLayout
和 NSURLSessionConfiguration
。
Block
Block 通常可以完全替代 delegation 消息传递机制的角色。但是我们要注意防止循环引用问题
Target-Action
Target-Action 是回应 UI 事件时典型的消息传递方式。iOS 上的 UIControl 和 Mac 上的 NSControl/NSCell 都支持这个机制。Target-Action 在消息的发送者和接收者之间建立了一个松散的关系。消息的接收者不知道发送者,甚至消息的发送者也不知道消息的接收者会是什么。如果 target 是 nil,action 会在响应链 (responder chain) 中被传递下去,直到找到一个响应它的对象。在 iOS 中,每个控件甚至可以和多个 target-action 关联。
基于 target-action 传递机制的一个局限是,发送的消息不能携带自定义的信息。在 Mac 平台上 action 方法的第一个参数永远是发送者。iOS 中,可以选择性的把发送者和触发 action 的事件作为参数。除此之外就没有别的控制 action 消息内容的方法了