iOS开发

简析KVOController实现原理

2016-04-30  本文已影响1295人  沐森iOS

KVOController是FaceBook的一个开源库,提供了方便的姿势让你去使用KVO。
https://github.com/facebook/KVOController
  大概的用法如下:

   [self.KVOControllerobserve:target keyPath:keyPath options:NSKeyValueObservingOptionNew block:^(id observer,id object,NSDictionary *change) {
    id newValue = change[NSKeyValueChangeNewKey];    
}];

observe操作完成后,在控制器 dealloc 时隐观测者会被隐式的移除,非常方便。
  我们来看看KVOController的实现流程:


KVOController实现流程:

1.Observer会创建一个FBKVOController的属性;

2.FBKVOController中包含一个NSMapTable的成员属性,用来存储observer的KVO信息;

3.FBKVOController创建一个_FBKVOInfo类型的实例,实例中存储了和KVO操作相关的信息(keypath等),然后将需要观察的对象Target作为Key,_FBKVOInfo的实例加入数组(对同一个Target的不同keypath的多次KVO操作)并把数组作为Value,存入步骤2中的mapTable中;

4.FBKVOController会调用_FBKVOSharedController的单例中的方法,同时将步骤3创建的info和观察的target传入给这个方法,这个单例进行了最终的KVO操作;

5._FBKVOSharedController的单例调用系统KVO方法,将自己作为观察者来观察Target对象。

在Observer内存被释放,执行dealloc时,其创建的FBKVOController属性的dealloc会通过KVOInfoMap找到所有KVO的对象,并执行移除观察的操作,十分巧妙的设计!
但是在使用的过程中还是有一些注意事项的:
 首先,FBKVOController使用block来传递系统KVO的回调,因此要注意retain cycle。
 其次,在使用的过程中,target不能强引用observer,否则也会形成retain cycle。我在上面的实现流程图中增加了一些标注来说明这个retain cycle是如何形成的:


retain cycle形成轨迹
红色的箭头代表了内存持有的方向,可以很清楚的看到形成了cycle。
针对v1.1版本,具有了一下新的特性:

针对 iOS/OS X/tvOS/watchOS 的 Carthage 支持 ( by @lexrus  by @nlutsenko);
提供了对 tvOS/watchOS 官方的 CocoaPods 支持 ( by @acerbetti,  by @nlutsenko);
所有的 API 都具有了 nullability annotations ( by @nlutsenko);
所有的对象集合(object collections)现在都具有泛型 ( by @nlutsenko);
新的工具宏(macros)以提供对键直观查路径(Key-Value Observing Paths)有效性的编译时检查 (by @nlutsenko);
支持 Xcode 7.3 和 Apple 开发最新的工具链 ( by @nlutsenko);

提升

NSObject+FBKVOController分类(category)现在被放置在一个独立的文件中(#36 by @ashton-w);
当尝试监控一个已经被监控的对象时不再有多余的警告信息;

修复

修复了当尝试从监控执行块(observing block)中移除监控者时可能引发的崩溃行为 ( by @siyusong);
修复并且提升了文档的可读性 (by @TongKuo  by @jeffreyjackson   by @ashton-w   by @jcavar   by @coeur )
Key-value 的监控是一个 MVC 应用中非常有用的技术,但接口丑陋古老。KVOController (来自 Facebook)构建了一个基于 Cocoa 的 time-tested key-value 监控实现,提供简单方便、线程安全的 API。

好处包括:

使用 Blocks、自定义 Actions 或者 NSKeyValueObserving 回调进行通知.
观测者移除时无异常
控制器 dealloc 时隐式的观测者移除
提升使用 NSKeyValueObservingInitial 的性能
线程安全并提供在观测者恢复时额外的保护 Thread-safety with special guards against observer resurrection – rdar://15985376.
上一篇下一篇

猜你喜欢

热点阅读