KVO进阶(一)

前言

KVO(key value observing),可以监听指定键,值的改变。与KVC相似,KVO也是以非正式协议的方式出现Foundation/NSKeyValueObserving.h

正文

相信大家对KVO的基本用法早已烂熟于心,这里不再介绍

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

在监听对象具体属性时,多数情况下会这样写

[obj addObserver:self forKeyPath:@"xxx" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

基于苹果的MVC设计原理,KVO最常出现的应用场景就是解耦ViewModel。以上代码中objModelselfController,当Model内容出现变动告知Controller,由Controller再更新UI

先来看一幅从NSHipster上截取的表

KVO进阶(一)_第1张图片
form nshipster

KVOcontext:后的参数是(void *)context,很明显这里应该写NULL而不是nil

接着context继续说,这个参数好像并没有什么卵用,不然干嘛每次都传空?
试想这样一种情况,B -> A -> NSObjectC -> NSObjectC中有属性obj

KVO进阶(一)_第2张图片
0-0
KVO进阶(一)_第3张图片
0-1

此时a、b同时观察c的obj属性,如果在某种情况下c的obj发生改变只想告知a而不告知b或者相反,这个时候怎么做?很简单,在B中重写-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context,如果不重写怎么完成需求?这个时候context就可以作为唯一标示符出场了。
同时还可以看到,obj的值改变后是先告知b再告知a的,也就是说谁最后观察谁最先被告知,类似于先进后出(这里与继承关系无关)。利用这一特性,又可以搞些小动作,比如跨类设置KVO的依赖(后续文章会介绍同一类的不同属性如何设置KVO依赖)。

KVO通知一样,可以是任意对象观察任意对象即“多对多”,observer并不仅限于Controller

你可能感兴趣的:(KVO进阶(一))