关于KVO

KVO大家应该都很熟悉的,我这里就献丑了,列几个简单的用法。

/**
 添加KVO监听

 @param observer 监听的对象,一般设置为self
 @param keyPath 被监听的对象,字符串的形式,比如"name","classroom.teacher"
 @param options 选择监听的值,NSKeyValueObservingOptionNew和NSKeyValueObservingOptionOld
位枚举,可以用|来同时使用
 @param context 上下文,一般可以用keyPath来判断监听。
但是keyPath存在风险,所以可以用地址来指定唯一的监听。
 */
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath 
options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
//添加对self对象的name属性监听:
    [self addObserver:self forKeyPath:@"name" 
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

//在dealloc的时候,注意移除监听,不然可能导致内存泄露甚至崩溃
- (void)dealloc{
    [self removeObserver:self forKeyPath:@"name" context:nil];
}

//监听方法,当属性name发生改变时,调用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"name"]) {
//change包含三个key值,kind,new,old
        NSLog(@"%@",change);
    }
}

以上就是我们常用的kvo用法,我最近在研究afnetworking源码的时候,发现了一种好玩的用法,与君共勉。

/**
 是否自动监听某个属性的改变,默认为true

 @param key 该属性key
 @return true 自动监听,false不监听
 */

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key{
    if ([key isEqualToString:@"name"]) {
        return false;
    }
    return true;
}

如果在类中实现这个方法,实现不对该属性自动监听时,改变属性的值,不会调用observeValueForKeyPath:ofObject:change:context:方法。

此时需要在修改name属性时,调用另外两个方法,才能监听到:

[self willChangeValueForKey:@"name"];
self.name = @"lzy";
[self didChangeValueForKey:@"name"];

你可能感兴趣的:(关于KVO)