iOS学习iOS开发iOS Developer

通信模式(Communication Patterns)

2017-07-28  本文已影响136人  __夏至未至

引言

看到标题的也许有一些老司机看过原文,此文是基于原文翻译加上自己理解,为了更好的学习iOS~(文章并没有写如何运用,主要是探讨什么时候用。)
原文地址:https://www.objc.io/issues/7-foundation/communication-patterns/

我们在开发过程中,常用的两个对象之间的相互通信的方式有很五种

Target-Action

这个方式相信大家见的就很多了,在写Button或者手势的时候,都会用到addTagert这个方法。Target-Action是用于在用户界面事件响应中发送消息的典型模式,一般是用于处理动作消息。他包含了 两个数据,一个是选择子(selector),还有一个是接收人(target)。在iOS中,能触发Target-Action事件的一般是基于UIControl的(官方文档说是可以任何对象,不过基本上都是继承与UIControl的)。一般的Target-Action的接收事件如下:

-  (void)dosomething:(id)sender;

在Target-Action中,消息的接收者其实并不知道发送者是谁,发送者也不知道消息的接送者是谁。所以当target是nil的时候,会通过响应者链找到某一个接收者去响应这个消息。这个方式的缺点就是传递消息的时候不能带着自定义的参数。

Delegation

Delegation在苹果自己的FrameWorks里就经常使用,比如我们经常用的 tableViewdelegatedataSource。它允许我们去自定义某一个对象的行为,也可以(被)告诉我们这个对象发生了什么。在这个通信过程中,消息的发送者需要知道消息的接收者,也就是这个delegate。我们在用UITableView的时候往往会写tableView.delegate = self,就是让tableView这个消息的发送者知道消息的接收者是谁(self)。这样的耦合度会很低,大家应该都深有体会吧,哈哈哈,有时候可能会找不到这个方法在哪儿。。。
delegate protocol可以定义任何方法,所以你也可以用这些方法传递你想要传递的参数,而且delegate protocol可以响应这些方法返回的参数。可见delegate protocol的通信方式是非常的灵活和直接。

block

block也叫闭包函数,讲道理的说,只要是Delegation通讯模式下可以做的事情,都可以用block代替。相对来说,block对于代码的整体性体验较好,不会散落在各地。但是blokc会造成循环引用,也可能会提前释放。总之block应用起来,总是对新手那么的不友好。
block的能够抓取当前上下文的命名域,怎么说呢,就是你不需要知道这个具体是什么东西,里面是怎么样的,你可以直接更具他给的参数或者直接写你想要写的代码。

KVO

KVO是一种通知对象的属性发生改变的机制。KVO是一种灵活的方式去监听当前对象属性的改变,尤其是对于系统属性的监听,比如说UITableViewContentOffSet这个值改变的监听,可以帮我们实现一些比较酷炫的UI效果(你懂的)。
KVO的使用,需要一些必要的条件,比如说你的对象要支持Key-Value Observing机制。而且你要知道这个对象的生命周期,在你不需要的时候移除这个KVO观察。

Notifications

Notifications这通讯方式,就是一种很好的,系统给我们封装好的,一对多的广播。他最大的优势就是可以跨越层级,对代码架构的解耦很有帮助。(现在好像不能说一对多是他的优势了,貌似Swift里有多Delegate)
iOS系统在应用过程中会发很多通知,比如说UIKeyboardWillShowNotificationUITextViewTextDidChangeNotification等等各种。
NotificationsKVO一样,需要知道接收者的生命周期,在最后生命周期结束的时候注销这个NotificationsiOS大部分的生命周期结束的时候都会调用- (void)dealloc。所以其实用起来也比较简单。(当然你要是发生循环引用导致当前对象不能释放,那就没办法了(⊙﹏⊙)b)。

讨论

对比了这五种方式,那我们什么时候用呢。上面文章的作者给了这么一张图:

通讯模式.png

我想分享下自己对于通讯模式的看法。因为不会画图,画在纸上的话,字太丑了,就写文字吧。。。。
1.是否直接进行对象的交互而且不需要参数,比如说手势,Button这些的 。如果是的话,就用Target-Action
2.是否是多层级的,两个对象是否有联系,如果不是的话,就可以用Notifications
3.既然两个对象是有联系的,当你需要监听值发生变化的时候,可以使用KVO。(单存值变化,而不是其他动作响应的情况下)
4.我是否需要知道这个对象的具体东西,上下文的具体命名域。如果不需要的话,这个时候使用Block会好一点。比如说我们网络请求时候的回调各种,只要输入请求参数,然后写好回调。中间发生了什么,其实你知道不知道,并不影响使用。
5.对于Delegationblock我觉得是大部分情况下是可以互相替换的,因为关于循环引用这方面,现在各种WeakSelf,StrongSelf的文章。不过在某些情况,比如说你的消息发送者需要用到接收者给的返回值的时候,这个时候用Delegation在设计上来说比Block更好。

End

其实对于通讯模式这种理解,对于整体架构,包括响应式编程都有很好的帮助。

上一篇下一篇

猜你喜欢

热点阅读