FBKVOConroller使用

FBKVOConroller是Facebook开源的替代KVO的解决方案。它用block解决了以前使用KVO时代码散乱的缺点。

FBKVOController的核心代码一共4个类:

NSObject+FBKVOController.h

NSObject+FBKVOController.m

FBKVOController.h

FBKVOController.m

NSObject+FBKVOController.m是一个Category。通过AssociateObject给NSObject提供一个Retain和nonRetain的KVOController。

FBKVOController.m一共可以分为3部分:

_FBKVOInfo

_FBKVOSharedController

FBKVOController

先来看一下FBKVOController这个类。首先该对象有2个属性,NSMapTable和pthread_mutex_t。

其中NSMapTable和NSDictionary类似,但是两者又有区别。

NSDictionary提供了key-to-object的映射。NSDictionary的object的位置是由key的hash值来索引的。由于对象存储在特定位置,因此要求key的值不能改变。因此,NSDictionary始终复制key到它的私有位置。这个key的复制行为也是NSDictionary如何工作的基础,但这也有一个限制:你可以只使用Objective-C对象作为NSDictionary的key,如果它支持NSCopying协议。此外,key应该是小且高效的,以至于复制的时候不会对CPU和内存造成负担。而NSMapTable是一种一般意义上的映射。不仅支持key-to-object,同时支持object-to-object映射。

pthread_mutex_t是一个互斥锁,用来保证多线程安全。

然后看初始化函数,对传入的observer进行weak持有,根据retainObserved来设置NSPointerFunctionOptions的值,初始化互斥锁。

FBKVOConroller使用_第1张图片

FBKVOController.png

再来看一下第一个API函数。如果object, keyPath或者block为空,则直接返回。接着根据传入的参数初始化_FBKVOInfo这个内部数据结构,然后调用[self _observe:object info:info]。

FBKVOConroller使用_第2张图片

observe.png

接着看一下- (void)_observe:(id)object info:(_FBKVOInfo *)info这个方法。先开一个锁来检查被观察的object的NSMutableSet是否存在,如果存在,则返回,解锁。如果不存在,为这个object添加一个NSMutableSet,接着NSMutableSet添加所传入的info,解锁。最后就是[[_FBKVOSharedController sharedController] observe:object info:info]。

FBKVOConroller使用_第3张图片

- (void)_observe:info:.png

那接着来看下_FBKVOSharedController这个类。_FBKVOSharedController这个类类似于一个中间件的注册表。所有的观察信息都由_FBKVOSharedController这个类注册,然后转发注册观察,并且更新info的state。

FBKVOConroller使用_第4张图片

observe:info:.png

最后看一下observeValueForKeyPath:ofObject:change:context这个方法。首先根据context上下文获取info信息。接着判断info的controller和observer是否存在(之前是weak持有)。根据info的block或者action活着override进行转发。

FBKVOConroller使用_第5张图片

observeValueForKeyPath:ofObject:change:context.png

作者:alvin_wang

链接:http://www.jianshu.com/p/1bf111d7d2de

來源:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(FBKVOConroller使用)