前言
在开发中我们经常需要用到KVO,但KVO一旦使用不当,会造成致命性的问题-崩溃。
在开发中KVO尝试过很多方法来使用KVO,有init方法中添加,dealloc方法中移除,如果有问题,在搞个布尔值标记下,网上很多方法在使用中可能场景和需求不一样,效果不保险感觉。
方案
今天偶尔看到MJRefresh框架在对KVO的处理,通过了解并Demo演练,发现这种方法非常不错,故此推荐给大家。
- (void)willMoveToSuperview:(UIView *)newSuperview;
这是系统的方法,当视图将要添加到父视图上,或将要从父视图上移除时会调用。在这个方法处理监听的添加和移除。Demo下载 先上代码
- (void)willMoveToSuperview:(UIView *)newSuperview
{
[super willMoveToSuperview:newSuperview];
NSLog(@"%s",__func__);
[self removeObserver];
if(newSuperview) {
if([newSuperview isKindOfClass:[ObserverView class]]) {
_obView = (ObserverView *)newSuperview;
[self addObserver];
}
}
}
- (void)addObserver
{
NSLog(@"%s",__func__);
NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew;
[self.obView addObserver:self forKeyPath:@"clickCount" options:(options) context:nil];
}
- (void)removeObserver
{
NSLog(@"%s",__func__);
NSLog(@"%@ -- %@",self.obView,self.superview);
/**
! 切记 这里必须用self.superview
self.obView 在这个时候已经是nill
*/
// [self.obView removeObserver:self forKeyPath:@"clickCount"];
[self.superview removeObserver:self forKeyPath:@"clickCount"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if([keyPath isEqualToString:@"clickCount"]) {
self.textlabel.text = [NSString stringWithFormat:@"%ld",self.obView.clickCount];
}
}
总结和注意点:
总结和注意点:
可在willMoveToSuperview: 添加和移除监听者
1. 需要调用super willMoveToSuperview
2. 需要先移除 监听者 removeObserver
3. 然后在willMoveToSuperview 参数 newSuperview 有值 设置监听者 addObserver
4. removeObserver 内如果是监听的父类,在这里必须写self.super 因为自己设置的属性指向父类,在这里属性是没值的