KVO背景
全称为Key-Value Observing,是iOS中的一种设计模式,用于检测对象的某些属性的实时变化情况并作出响应。
使用步骤
系统框架已经支持KVO,所以程序员在使用的时候非常简单。
1. 注册,指定被观察者的属性,
2. 实现回调方法
3. 移除观察
使用方法
1、在初始化方法中加入:
[_tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
2、添加默认的响应回调方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (object == _tableView && [keyPath isEqualToString:@"contentOffset"]) {
[self doSomethingWhenContentOffsetChanges];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
3、在dealloc中移除KVO监听:
[_tableView removeObserver:self forKeyPath:@"contentOffset" context:nil];
要注意的问题
1、KVO的陷阱
KVO有一种缺陷,KVO的add和remove必须成对出现,当对同一个keypath进行两次removeObserver时会导致程序crash。
KVO是以队列的形式管理的,即先进先出,执行remove操作时,会remove掉第一个add的KVO。
2、Context的用处
当同一个属性有两个KVO时,此时如果context值为nil,则执行remove时,便无法确保remove掉正确的KVO
对于这种情况,可以分别定义context字符串,比如第一个KVO定义context为@"FirstKVO";然后在dealloc中remove observer时指定移除的自身添加的observer。
3、UIKit不支持KVO
利用KVO来监听UITextField的text属性时,会发现在代码中设置text属性,可以响应observeValueForKeyPath函数,但如果在界面上输入文字时,却无法响应,这是因为UIKit不支持KVO机制,当用户通过键盘输入文字来改变textView的text,并非通过set方法为text赋值,也就不会触发监听事件!
如果一定要用KVO来监听的话,可以实现 TextView 的代理-(void)textViewDidChange:(UITextView *)textView;在这个代理里面加入textView.text = textView.text即可。