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<NSKeyValueChangeKey,id> *)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"];