什么是KVO?
KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制。
该如何使用?
1.注册,指定被观察者的属性
[object addObserver:self forKeyPath:key options:NSKeyValueObservingOptionNew context:nil];
参数说明:
object:被观察的对象
observer:观察者对象
keyPath:被观察对象的属性名称
NSKeyValueObservingOptions:有4个值
NSKeyValueObservingOptionNew 监听它的新值
NSKeyValueObservingOptionOld 监听它的旧值
NSKeyValueObservingOptionInitial 监听初始化
NSKeyValueObservingOptionPrior 分2次调用。监听旧值和新值
context: 可以带入一些参数,任何类型都可以,强制转就可以。
2.实现回调函数
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"keyPath---->%@ change--->%@",keyPath,change); }
参数说明:
keyPath:被观察对象的属性名称
object:被观察的对象
change:新值或者旧值
context:对应的context
3. 移除观察
[object removeObserver:self forKeyPath:@"name"];
参数说明:
object:被观察的对象
observer:观察者对象
keyPath:被观察对象的属性名称
写个测试程序测试一下:
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject { @private NSString *address; } @end
Person.m
#import "Person.h" #import "Car.h" @interface Person () @property (nonatomic ,strong) NSString *name; @property (nonatomic,strong)Car *car; @end @implementation Person -(id)init { self=[super init]; if(self){ self =[super init]; self.car=[[Car alloc]init]; } return self; } @end
Car.h
#import <Foundation/Foundation.h> @interface Car : NSObject @end
Car.m
#import "Car.h" @interface Car() @property (nonatomic ,strong) NSString *brand; @end @implementation Car @end
测试代码:
//添加KVO观察者 -(void)addObserver { [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld context:@"haha"]; [self.person addObserver:self forKeyPath:@"address" options:NSKeyValueObservingOptionNew context:nil]; [self.person addObserver:self forKeyPath:@"car.brand" options:NSKeyValueObservingOptionNew context:nil]; } -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"keyPath---->%@ change--->%@",keyPath,change); } //移除KVO观察者 -(void)removeObserver { [self.person removeObserver:self forKeyPath:@"name"]; [self.person removeObserver:self forKeyPath:@"address"]; [self.person removeObserver:self forKeyPath:@"car.brand"]; }