在APP中 如何选择delegate、notification、KVO

从上学开始英语一直是我的弱项,但是必须要敢于直面自己的弱点,所以从现在开始要计划时不时的搞一搞英文原文文档以此弥补自己的弱点。不过能力一般,水平有限,先将原文奉上,并请大神们收下我的膝盖。
英文原文

梦想之地: 澳大利亚 大堡礁

一个公共问题是我们根据经验开发iOS应用时,在不耦合的情况下如何进行控制器之间的通讯,在iOS开发中有三种不同的方案可以解决这个问题

Delegation:为控制器设置代理
Notification Center:设置通知
Key value observing:KVO

那我们应该明白这三种方案的优缺点,以便更好的使用在我们的项目中。
接下来的对于这三种方案的讨论完全是我开发iOS应用的个人见解。
我会讨论我觉得某一个特定的方案在某些情况下为什么比另一种方案好。我不给不了绝对的答案,只是一些个人见解而已。所以请各位大神在留言区自由讨论以便能给予我更多的经验和见解。
言归正传,先科普一些这三种方案到底都是什么。

这三种模式都是在没有耦合的情况下将一个对象的事件传递到另一个对象。他们是对象发送通知后按照某些途径的传播的方式,更准确的说,是让某些事件被响应对象接受到的方法。这是一种在对象间常见的必须执行的任务,如果控制器间无法进行通讯,这整个应用则无法融为一体。然后控制器的另一个作用就是必须实现自我控制。我们希望我们的控制器可以独立存在,控制器之间不存在耦合,这样方便抽取与复用。控制器可以创建其他控制器并且可以自由的联系,但是我们不想在创建控制器的时候绑定太多信息到父类中。如果控制器间产生了过多的耦合,这产生很多问题,使之失去了重用的能力,这样难以在后期维护与复用。

这三种设计模式提供了再控制器或者对象中相互联系的方法,而且不会产生耦合。我将会描述这么模式和在iOS中如何应用。不过需要注意他们在某些条件下可能不适用,这也是我后来需要讨论的内容。

代理模式

当你第一次启动iOS应用程序,你会注意到在系统提供的SDK中很多地方都是使用了 “delegates” 。代理在iOS并不算是一种固定的设计模式,这取决于你有什么样的变成背景,你可能不会立刻就想起来使用代理明显的优势和为什么他经常性的被使用。
关于代理最基本的想法,是控制器定义一套协议(定义一套方法)描述控制器需要做什么操作已让另一个控制器做出响应。这个协议需要相应控制器遵守,仿佛代理再说“如果你想成为我的代理,你必须是写这些方法”。这是控制器实现这些代理方法,相应控制器会响应相应的方法,代理可以是任何对象类型,所以控制器之间并不存在耦合,但是代理响应时,可以传入信息,告诉响应控制器相应的动作和参数。
优点:

  • 严格的语法。所有的事件都需要在协议中清除的定义。
  • 如果代理没有事件的话编译器会发出警告或报错。
  • 协议定义的范围仅在控制器内, 只有控制器能定义代理。
  • 可追踪性强,方便debug
  • 同一个控制器可以同时遵守多个协议,
  • 不需要第三方对象进行监控,使用简单。
  • 代理可以通过方法传值,这样在不同控制器之间可以进行参数传递。

劣势:

  • 需要写很多代码才能实现功能1,协议定义 2.代理需要在控制器中进行赋值,3在响应控制器中需要实现方法。
  • 需要检查代理是否为空,如果调用空代理的话会导致程序崩溃。
    代理只能是一对一操作,不能实现一对多操作。

通知

iOS应用中有一个“通知中心”的概念。它允许一个对象发生通知后其他的对象响应通知。系统允许一个对象产生通知后再任何其他对象中以较低的耦合为代价就可以接受到通知并且响应事件和传递变量。这个方案的最基本概念是通过控制器使用一个件(通知名称)以允许其他的对象能够接受到该控制器中的特殊事件。然后其他的控制器,对象通过注册相同的通知事件以便能接受到接受到事件。
优点:

  • 方便使用,无需过多的代码。
  • 对个对象可以同时响应一个通知。
  • 控制器可以通过上下文(字典)自定义信息(userinfo)通过通知进行传递达到传值的效果
    缺点:
  • 无法在编译阶段检测错误,通知的正确性都是通过开发者来判断
  • 如果你要销毁注册通知的对象时,需要在消息中心取消注册了的通知
  • 在调试的时候通知会导致非常难以追踪。
  • 需要第三方对象来管理控制器和观察者之间的关系。
  • 所有观察者和控制器需要提前知道通知名称和userinfo dictionary key。如果不在公共区域定义这些名称,他们会非常容适出现无法同步的现象。
  • 在通知发出后控制器不在就不能从观察者获得任何的反馈信息。

Observation

Key value observing (KVO)是一个对象能够观察另一个对象的值,并且可以捕获到改变。前两个方案(代理和通知)更加适合一个控制器和其他对象的通讯,然后KVO更加适合任意的一个对象监听任何其他对象的属性的改变(不一定单单指一个控制器)。这是一种我们能够保证同步的保持和另一个对象同步的方法;及时当一个对象的状态改变时,另一个对象也可以及时作出反应。他只能用于对于对象的属性作出反应,不能对方法和动作作出反应。
优点:

  • 可以方便的在两个对象之间同步信息,例如一个model和一个view。
  • 允许我们对非我们自己创建的对象即内部对象响应属性值的改变,而不需要改变其内部实现(SDK objects)。
  • 可以提供给我们之前观察的对象的变化前的值和变化后的值。
  • 可以用use key观察属性,也可以观察嵌套对象。
  • 完成了对观察对象的抽象,不需要额外的代码来允许观察者进行观察。
    缺点:
  • 我们观察的属性必须定义为string类型。这样编译器就不能做出检查。
  • 重构属性可能会导致我们的观察者无法继续工作。
  • 如果要同时监听多个值,可能会使用"if"等复杂语句。因为所以的KVO代码都是通过一个方法执行。
  • 当对象销毁时需要移除观察者。

选项总结

这三种方案都存在各种的优点与缺点,我们如何对这些方案进行汇总并且从中选取最佳方案。选取每个方案都没有绝对的对与错。每种方案都提供了一种模式让一个对象监听另一个对象的信息改变,信息提供者并不需要知道监听者的信息。在这三种方案中我想KVO有最清晰的使用案例,而且对于需求有清晰实用性。而另外两种方案有着像是的用法,经常用于在控制器之间的通讯,所以我们在实际使用时如何进行选择。
在我个人的iOS开发经验中,我看到代码中使用Notification方案频率比较高。我个人不喜欢使用notification center。我发现在开发中使用通知太难进行跟踪流程了,对于用户信息的键值和用户信息字典需要进行同步,这样一来就有太多的信息需要定义在公共区域。这对于刚接手项目的开发者来说需要太多的时间来熟悉代码,尤其是拥有如此多通知的工程。
我坚信用规范的命名规则定义协议方法。会使控制器之间进行通讯变得非常清晰简洁。通过努力定义这些协议方法会写出更多易于阅读的代码由此对于你的APP 可以提供更多的可追溯性。编译器可以获取代理方法的改变和使用,在编译器可以提前发出警告。而不会任由APP不响应代理方法。即使一个代理方法需要响应多个控制器,只要你的APP有良好的结构,逐级向上级控制器响应代理方法,也可以在多个控制器中响应一个代理方法。
当然也有例外,在代理方案不适合而通知方法使用起来更有意义。例如在你的APP中某个事件都需要知道,然后这种情况是非常罕见的。另外一个例子是当你建立了一个架构而且需要通知该事件给正在运行中应用。
根据经验,如果是属性层之间的事件,不管是在不需要编程的对象还是在紧紧绑定一个view对象的model对象,我只使用KVO。对于其他的时间,我通常会选用代理模式,如果有特殊原因无法使用代理,我会想想是不是我的app架构出了问题才无法使用代理。除非遇到这种情况我才会使用通知。

Tips:这是我的第一篇翻译博客,感触颇多。深深的了解道路自己的水平太差,这样基本上知识点都知道的小东西还搞了这么久,不过指责过去不努力已经没用了,只有不断的向前才行。
同时也希望能看到的童鞋们多提意见哈。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,496评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,097评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,563评论 25 707
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,014评论 11 349
  • 今日做下的事: 跑步,练散打,看小说。 武协摆点,派票,收点。 想表演内容的细节,写日记总结。 武协散打队排演带训...
    文建伟CZYH阅读 287评论 0 0