我对于iOS的KVO的理解基于Objective-C

来源:互联网 发布:java集合类原理 编辑:程序博客网 时间:2024/06/07 22:54

我对于iOS的KVO的理解基于Objective-C

由于iOS的程序采用MVC架构,如果M需要发送数据给C的时候,不能直接访问C的对象成员,而必须通过一些间接的方式,KVO就是这么一种方式,除了KVO,还可以用Notifications或者delegate来达到目的,我一直以来对KVO不大了解,不过最近通过一些实践之后,对这方面有了一些体会,正趁此机会整理一下。
就我的理解,KVO应该是iOS编程特有的一种概念,它应该是基于objective-C这种语言的,别的语言好像没有这样的特殊功能。
KVO全称是Key Value Observer,这里面最关键是要理解什么是Key,它说白了就是module里面的某个变量,这个变量可以是一个int型,NSString或者其他的对象,这个key我们并不需要特别对它进行处理,而是我们想看它就随时可以看。举例来说,我们需要监控网络发过来的一个时间值,假设它的变量是remoteTime,如果收到这个时间值,就需要在主界面更新时间信息,那么如果不使用KVO,我们通常可以在Controller里面设置一个timer,按照一定的时间间隔查询Module.remoteTime,如果发现它变化了,就更新UI。如果采用KVO,则可以不必用timer,而直接在监听到remoteTimer被写入新的数据时被通知得到,这是一种很神奇的设计,好像实现了一种中断的触发。下面是一段代码:
在module的代码里给remoteTime写入新的数据:
self.remoteTime = [[res objectForKey:@"position"] integerValue];
在viewController的代码里,viewDidLoad方法里加入观察者和要观察的key:
[[JsonProtocol share] addObserver:self forKeyPath:@"remoteTime" options:NSKeyValueObservingOptionNew context:nil];

这里是使用KVO的第一步,就是告诉系统谁给谁加入观察者,在这个例子里,JsonProtocol是被观察者,viewController也就是self是观察者,所以是JsonProtocol 调用addObserver方法把self加到它的观察者列表之中,然后keyPath对应的是JsonProtocol中的变量名,这里要把变量名以String的方式传人进去;option和context暂时先不介绍。

第二步就是写下面的方法,当要观察的key发生变化时,会执行下面这个方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{    if ([keyPath isEqualToString:@"remoteTime"]) {//        NSLog(@"change %@",change);        NSInteger remoteTime = (NSInteger)[[change objectForKey:@"new"] integerValue];}

注意,假如有多个被观察的key,他们的入口都在这里,所以要在里面分别做判断。可以通过change取出变量的值,还有一种办法是通过object取出。

第三步是移除观察者,这一步是不可少的,在viewController的dealloc方法里把observer remove掉


- (void)dealloc{
[[JsonProtocol share] removeObserver:self forKeyPath:@"remoteTime"];
}

上面这一点也有一点要特别注意,就是必须由JsonProtocol来调用removeObserver方法,而不是self,我之前写成了这样:
[self removeObserver:self forKeyPath:@"remoteTime"];
结果在推出viewController之后就崩溃了。之所以会犯这样的错误,是因为我一开始没有搞清楚KVO的概念,KVO主要是由被观察者,也就是observed来主动完成的,而observer是被动接收。但相关的3步动作都是在observer端完成,observed端的代码是不需要修改的。当然如果只是想试验着玩一下的话,可以把被观察的变量都写在viewController里面,就相当于observer自己观察自己。

原创粉丝点击