IOS KVO

作者: chenhh6701 | 来源:发表于2017-06-19 15:23 被阅读46次

刚入坑的小白,一开始以为KVO完全可以用代理模式替代,在MJRefreshComponent中看了KVO的代码后,突然明白KVO比我想象的强大。

对比代理的优势:

1.他不需要在被监控类中添加Delegate,被监控的类完全不需要知道定义的业务逻辑,不过需要添加addObserver 和 removeObserver。
2.KVO中被监控的类可以被多个对象监控,而代理模式只有一个delegate(除非你再写一个list,这样添加了被监控对象的功能,不实际)。

代理的优势:

1.KVO只监听值的更改,而delegate一般带有业务逻辑(对应值变化不同有不同的方法)

注意点:

1.一个需要注意的地方是,KVO 行为是同步的,并且发生与所观察的值发生变化的同样的线程上,不推荐把 KVO 和多线程混起来。

方法:

// 该键名 所依赖的其他键 (其他键更改,该键也会调用一直set)

  • (NSSet *)keyPathsForValuesAffecting<键名>
  • (void)willChangeValueForKey:(NSString *)key
  • (void)didChangeValueForKey:(NSString *)key

NSKeyValueObservingOptions

KVO的使用:

在MJRefreshComponent的使用

// 添加监控
- (void)addObservers
{
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil];
    [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil];
    self.pan = self.scrollView.panGestureRecognizer;
    [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil];
}

// 移除监控
- (void)removeObservers
{
    [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset];
    [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize];;
    [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState];
    self.pan = nil;
}

// 对应值的更改
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    // 遇到这些情况就直接返回
    if (!self.userInteractionEnabled) return;
    
    // 这个就算看不见也需要处理
    if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) {
        [self scrollViewContentSizeDidChange:change];
    }
    
    // 看不见
    if (self.hidden) return;
    if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) {
        [self scrollViewContentOffsetDidChange:change];
    } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) {
        [self scrollViewPanStateDidChange:change];
    }
}

参考:
https://objccn.io/issue-7-3/

相关文章

网友评论

    本文标题:IOS KVO

    本文链接:https://www.haomeiwen.com/subject/fcggqxtx.html