为了方便监听一个数据在改变后,得到通知,用KVO 还是比较方便,kvo 的实现原理,当一个object有观察者时,动态创建这个object的类的子类;在这个派生类中重写基类中任何被观察属性的 setter 方法,派生类在被重写的 setter 方法实现真正的通知机制,然后作出相应的响应;
简单的实现KVO 分3部
实现方法
先定义一个model类,
@interface Model : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@end
然后在VC初始化,model,并且注册KVO监听model 的name属性,并且在5秒后修改他的name值
- (void)viewDidLoad {
[super viewDidLoad];
Model *model=[[Model alloc]init];
model.name=@"aa";
/** model是被观察者, self 是观察者, name 是被观察的属性, options 是修改前,修改后的信息 **/
[model addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
//5秒后修改他的name信息
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
model.name=@"update data";
});
添加监听方法,
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
NSLog(@"%@",change);
}
发现崩溃了,,因为在ARC环境下,model默认是weak属性,出了viewDidLoad方法后直接被回收了,所以说需要定义model 强引用才可以**
@property(nonatomic,strong) Model *model;
这样才能保证安全,并且在离开此页面的时候记得remove
-(void)dealloc{
[_model removeObserver:self forKeyPath:@"name"];
}
利用系统的KVO 方法,必须要注意释放,也无法实现block 方式实现,麻烦,推荐FBKVOController,线程安全的KVO ,并且方便实用,使用方法如下
@interface ViewController (){
FBKVOController *_fbKVO;
}
- (void)viewDidLoad {
[super viewDidLoad];
Model *model=[[Model alloc]init];
model.name=@"Y.X";
//初始化
_fbKVO=[FBKVOController controllerWithObserver:self];
//注册通过block 方式直接获取监听
[_fbKVO observe:model keyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
NSLog(@"%@",change);
}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
model.name=@"update data";
});
上面就是简单的FBKVOController 实现的kvo监听,并且FBKVOController 提供了block, action:(SEL)2中方式实现监听;同时可以对model 多个属性进行监听,如下
//keypaths 添加多个属性,就可以了,然后在别的地方修改model 的多个属性的值,这里都可以监听到的,
[_fbKVO observe:model keyPaths:[NSArray arrayWithObjects:@"name",@"sex",nil] options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
NSLog(@"%@",change);
}];
以上就是kvo 的简单实现,和FBKVOController 的使用,推荐FBKVOController实现kvo
功能,方便简单,保证线程安全,