iOS消息传递机制

https://www.objccn.io/issue-7-4/

什么时候用KVO、通知、delegate、block

KVO

适用场景

关心的是一个值的改变,带来的影响,或者可能在多处,会改变一个变量的值,然后我们都要去做一系列由于这个变量的值改变而发生的其他响应。例如,一个变量A,如果A>0,按钮B就可点,否则B就不可点。如果不使用KVO,我们需要在所有A = 的地方,更改B的状态。如果程序里A的改动可能出现在很多处,每一处A的改动都要更改B的状态。如果使用KVO,将A的值,和B的状态绑定在一起,那么在程序的所有地方,只要放心的对A进行改变就可以了。B的状态一定是正确的。这里的绑定专门有一个框架ReactiveCocoa,其实就是通过KVO实现数据之间的绑定,常用在MVVM架构中实现数据的传递。

使用注意事项

  1. 由于一个VC中,注册的KVO其实都走一个代理方法,所以一定要注意父类有没有实现这个代理方法。
  2. 必须在合适的时候进行removeObserver。
  3. 另外对同一个KeyPath进行两次removeObserver是会导致crash的。
  4. 如果要在 Core Data 上使用 KVO 的话,方法会有些许差别。这和 Core Data 的惰性加载 (faulting) 机制有关。一旦一个 managed object 被惰性加载处理的话,即使它的属性没有被改变,它还是会触发相应的观察者。

通知

适用场景

非常适合A和B是夸模块的,或者两者都不知道对方,发送者甚至不知道有没有接收者。并且通知是单向的,接收者也无法恢复发送者。

delegate

适用场景

发送者是知道接收者的,delegate通过protocol可以定义任何方法,可以选择传递任何参数,使用起来很灵活。并且相关的对象只有发送和和接收者(这点和通知不同,一旦发送者发送通知,其实所有的注册的对象都可以作为接收者,所以就开了一道口子)。

使用注意事项

定义delegate一般为weak,因为往往会成环。造成循环引用。我们最常见的使用delegate的场景:A有一个B,B的delegate属性=A(A实现B的delegate),也就是A强引用B,B又强引用A(如果delegate定义为strong)。

Block

适用场景

首先,Block 通常可以完全替代 delegation 消息传递机制的角色。不过这两种机制都有它们自己的独特需求和优势。block最大的好处就是如果将处理的消息和对消息的调用放在一起可以增强可读性,而且可以访问定义block同一个域的变量,使用起来十分方便。

使用注意事项

  1. block当然是循环引用了。
  2. 除了我们常用的weakSelf、strongSelf外,解决循环引用还有一种常见的方式,就是执行完block,将block属性设置为nil(也打破了环)。
  3. 如果在block里改变定义block时候同一个域里的变量,需要将变量定义为__block。

Target-Action

一般用于UI响应事件,基于 target-action 传递机制的一个局限是,发送的消息不能携带自定义的信息。在 Mac 平台上 action 方法的第一个参数永远是发送者。iOS 中,可以选择性的把发送者和触发 action 的事件作为参数。除此之外就没有别的控制 action 消息内容的方法了。

posted @ 2017-04-12 17:01  张驰小方块  阅读(239)  评论(0编辑  收藏  举报