iOS上KVO对比之 FBKVOController 与 GYDKeyValueObserver

前言

OC语言存在已久,其中有很多大家喜欢的设计,也有很多令人头疼的设计,更有让人又爱又恨的设计,KVO就是其中一项。好处自不用说,最令我遗憾的有2点:

  1. KVO的添加和触发并非线程安全。
  2. 同一个回调函数导致多个KVO之间可以互相干扰。
    为此除了自己简单封装了一下,也在网上搜索了一下别人的处理,其中知名度最大的无疑是 FBKVOController。那么就来对比一下吧。
    附上链接
    FBKVOController https://github.com/facebookarchive/KVOController
    GYDKeyValueObserver https://www.jianshu.com/p/a25260631d8f

线程安全

KVO是用来监听属性变化,那么第一个要考虑的线程安全问题便是:当我们在一个线程上添加和移除KVO的同时,这个属性在另一个线程上发生变化。以 FBKVOController 为例


线程安全问题

结果是不出意料的crash了,换成自己封装的 GYDKeyValueObserver 也是同样crash。
在网络上尝试搜索了一下,没有发现苹果API里有这处线程安全的参数配置,也没有发现有谁来解决,甚至没人把这当成一个问题,毕竟触发条件太苛刻。那么我们也不把这当成问题了。

KVO之间的干扰

这次先说 GYDKeyValueObserver
每一个KVO都用一个单独的对象来管理,彼此完全隔离。如下图:


GYDKeyValueObserver的效果

GYDKeyValueObserver的使用方式就如同最常见的变量赋值一样,怎么赋值就怎么监听,不赋值就不监听。使用KVO就如同使用一个最普通的OC对象。如下图:


GYDKeyValueObserver的使用

如果不知道如何使用OC对象,请自行学习。

再来看 FBKVOController
FBKVOController也是使用对象管理KVO。不仅如此,还可以使用同一个对象管理多个KVO,但有一个额外的要求,那就是不能监听同一个属性。如下图:

4.png

当第一个对象监听了key1之后,再想监听key1就要创建另一个对象,否则是无效的。也就是说,是否能使用一个对象管理多个KVO,取决于你是否对监听了哪个对象的哪些属性了如指掌,而这一点正是我们难以做到的。我们本是为了不用去考虑多个KVO之间的关联而封装了一个对象,如今为了判断多个KVO能否用同一个对象管理时,又需要去考虑这些KVO之间的关联,可以说是本末倒置了。

代码量

GYDKeyValueObserver 实现文件一共59行,除去开头注释,方法定义,非空判断等,逻辑代码在10行左右,简单到不好意思说成封装😂。也就是不知道发什么文章好了才拿出来凑数。
FBKVOController 实现文件一共676行,查看代码之后可以发现,大部分代码都是用来处理同一个对象管理多个KVO时的逻辑。

参数细节的区别

在参数细节方面 FBKVOController 做的比较全面,回调的方式有block和SEL可供选择,而 GYDKeyValueObserver 为了一切从简,只提供了block方式,需要使用者会使用block。
FBKVOController block的参数包括observer和object,从而免除这2个对象的weak处理。当然代价是需要提前设置好observer。而 GYDKeyValueObserver 为了一切从简,只提供了object参数(以前没有,最近刚加的),用户不用提前设置observer,但需要使用的时候,还需要做好weak处理。
FBKVOController 可以一次设置监听多个属性,GYDKeyValueObserver只能一次一个。但是平时写代码时就有人喜欢把多个代码耦合在一起,然后写一堆if else处理,也有人喜欢把代码分开,每个功能独立处理。我是后者,所以虽然FBKVOController接口更丰富,但这个功能对我无用。

总结

对于开发者来说,首先使用自己最了解的方式。如果都不了解,GYDKeyValueObserver是更好的选择,代码量小到一眼看透,傻瓜式用法一眼学会。

课后思考

可以说原本用10句代码已经能得到90分的成绩,FBKVOController又加入了100句代码将成绩降低到90分,是否值得?具体点就是,一个对象管理多个KVO,并且不能监听同一个key的必要性在哪里?那么来思考一个对象管理多个KVO的目的。
查看FBKVO内部代码发现其内部不但没有少建对象,反而因为要管理而建了更多的对象,并且还要加上线程安全处理,对于FBKVO本身来说没有任何好处。
而对于FBKVO外部的表现形式只有一个,就是少创建了变量,通常是成员变量,但我们通常对KVO的使用数量不多,能创建成员变量的情况下为每个KVO都创建一个成员变量并不影响什么,好处可以忽略。
那么还剩不能添加成员变量的情况。例如在其子类,分类,或者别的类里,为一个不想或不能修改代码的类扩展新的KVO处理,这时候自然是不能为其创建成员变量,但是同样的,这种情况下如果想利用一个已经提前定义好的成员变量(其指向的FBKVO对象),就要检查类本身的代码里,以及项目所有的代码里,有没有和我们一样利用这个变量又监听了同一个属性的。并且别人在开发代码时也要做同样的检查,不同分支合并时还要都再检查一遍。每次检查的结果如果是没有,那么恭喜你可以用了,而如果有,那么还是要重新创建一个变量。虽然出问题的概率也很小,但如果对自己的代码负责,我们就必须要做到。(手动表情:我要这封装有何用!)想到这里,我宁愿直接定义一个新变量。
思考的结论:在如此明显的情况下,FBKVOController依然这么做了,那只能说明FB内部还有一套与其配套的开发框架,例如充分利用KVO实现数据驱动一切的开发方式。
对于只有一个单独FBKVOController的外人,其内部多做的那些处理,只让那些性格随意不拘小节的人可以轻微的偷懒,对于严谨负责的人来说只是累赘。

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

推荐阅读更多精彩内容