作者:代培
地址:http://blog.csdn.net/dp948080952/article/details/53819944
转载请注明出处
前言
写这篇博客的原因是昨晚需要用到KVO,只是要用最简单的KVO,观察一个属性,在其改变时得到通知,然而到网上找了许多博客,看了许多文章,都是长篇大论介绍了一大堆什么是KVO,然而看完我还是一脸蒙逼,我只是想要快速部署,你跟我说那么多干嘛,最后还是自己写了一个Demo跑通了,这里就写一篇博客,记录一下如何部署一个最简单的KVO,让有同样需求的人能够在最短的时间里部署KVO。
正文
前期准备
首先说一下部署KVO需要准备什么:
- 一个被观察者
- 一个被观察的属性
- 一个观察者
当然被观察者和观察者可以是同一个,我下面的例子中观察者和被观察者都是一个ViewController。
具体步骤
1.被观察者调用这个方法注册一个观察者:
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
感觉这个API很难用,刚看到的时候根本不知道后面两个参数该传入什么,Mattt Thompson是这样吐槽这个方法的:让这个API不堪入目的事实就是最后两个参数经常是 0 和 NULL。
2.观察者实现下面这个方法,当观察的值改变了,此方法就会被调用:
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;
3.移除观察者
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
一个最简单的实现
上面的方法具体怎么用我都没解释,但是怎么解释都没有一个例子来得直接,下面我们就上代码,talk is cheap, show you the code!
我们新建一个Single View Application,然后就在这个默认的VC里操作。
首先加入一个属性
@property (nonatomic, assign) NSInteger count;
然后在viewDidLoad
中注册观察者。
[self addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew context:nil];
context的值可以直接设为nil
然后实现观察者的方法,在这个方法里可以做一些刷新UI的工作
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%li", (long)self.count);
self.label.text = [NSString stringWithFormat:@"%li", (long)self.count];
}
然后点击button的时候修改属性值,这里要注意的是一定要用点方法赋值,而不能直接修改属性对应的成员变量,比如此处改为_count++
KVO就会失效,也不要重写该属性的setter方法,不然也可能引起失效。因为自动合成的setter方法是使用KVC中的方法:- (void)setValue:(nullable id)value forKey:(NSString *)key
,KVC(键-值编码)是KVO的基础
- (void)buttonClicked:(UIButton *)sender {
self.count++;
}
最后最重要的一点,取消注册。当一个观察者完成一个监听需要取消移除这个观察者。通常这个动作是在-dealloc
或-observeValueForKeyPath: ofObject: change: context:
完成的,这里就是在-dealloc
完成的
- (void)dealloc {
[self removeObserver:self forKeyPath:@"count"];
}
至此一个最简单的KVO就完成了,其实很简单,而且这种简单的模式在很多时候都已经够用了,如果需要这个demo的代码可以去我github下载。
注意
使用KVO时需要注意几个问题:
1.添加观察者时注意key不能出错,不然会崩溃
2.完成监听一定要取消注册,不然程序可能也会崩溃
3.移除监听时也可能会出现崩溃,如果重复移除或移除一个你没有注册的监听
对于1和3中的问题,如果实在没法避免可以用try catch来包裹。
总结
KVO中值得挖掘的东西很多,这只是一篇十分浅薄的记录,希望能够帮助大家,后面有机会还会深入学习KVO,最后让我膜拜一下Mattt Thompson,他的文章真是有深度,能够学到很多,本文就参考了他的文章。
本文参考了如下文章: