标签:
KVO即键值观察者,它提供了一个观察者模式,用于监听某个对象属性值的变化,可以实现一个观察者,一个被观察者,多个接收者之间的通信关系。
KVO的工作流程:
1.被观察者属性发生变化(child对象的cleanValue发生变化)
2.观察者监听到属性的变化(KVO帮我们实现了观察者的业务逻辑)
3.观察者会调用观察者方法通知到事件的接收者(观察者通知到保姆)
4.事件接收者响应这个事件。
在接收者类中添加小孩的观察者,对象写self,下面实现观察者方法,其中改变小孩的相关属性值,最后手动移除观察者
相关方法:
1、添加观察者的方法:
_child:被观察者
addObserver:事件的接收者
options:表示在观察者方法的change参数中能够获取的值。
context:传递的参数
[_childaddObserver:selfforKeyPath:@"cleanValue"options:NSKeyValueObservingOptionNewcontext:NULL];
2、观察者响应事件的方法:
//keyPath:被观察者监听的属性名
//object:被观察者
//change:是一个字典,提供了关于KVO的有效信息,比如key:new时表示的是属性变化后的新值,key:old表示的是属性变化前的旧值
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {}
举例:小孩脏了,需要保姆来打理
给小孩添加一个观察者,事件的接收者是保姆,观察者把小孩洁净度这个属性值传递到保姆,保姆去响应打理小孩的方法。
#import "Child.h" @implementation Child - (instancetype)init { if (self = [super init]) { _cleanValue = 100; _happyValue = 100; } [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; return self; } - (void)timerAction:(NSTimer *)timer { //1.只有通过两种方式进行属性值的设置才能被KVO所监听到 // (1)用setter方法 // (2)KVC //这种方法不能被KVO监听到 // _cleanValue--; // _happyValue--; self.cleanValue = _cleanValue - 1; self.happyValue = _happyValue - 1; NSLog(@"cleanValue:%li,happyValue:%li", _cleanValue, _happyValue); } @end
#import "Nanny.h" #import "Child.h" @implementation Nanny - (instancetype)initWithChild:(Child *)child { if (self = [super init]) { _child = child; //使用KVO来监听小孩属性值的变化,需要给小孩添加一个观察者,必须在注册观察者以后才能够监听到小孩属性值的变化。 /* 给被观察者注册一个观察者,来监听被观察者属性的变化。 _child:被观察者 addObserver:事件的接收者 options:表示在观察者方法的change参数中能够获取的值。 context:传递的参数 */ [_child addObserver:self forKeyPath:@"cleanValue" options:NSKeyValueObservingOptionNew context:NULL]; [_child addObserver:self forKeyPath:@"happyValue" options:NSKeyValueObservingOptionNew context:NULL]; } return self; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { //keyPath:被观察者监听的属性名 //object:被观察者 //change:是一个字典,提供了关于KVO的有效信息,比如key:new时表示的是属性变化后的新值,key:old表示的是属性变化前的旧值 NSLog(@"%@", change); if ([keyPath isEqualToString:@"cleanValue"]) { NSNumber *newValue = change[@"new"]; if ([newValue integerValue] < 95) { //保姆针对小孩脏了事件的处理代码 NSLog(@"保姆给小孩洗白白"); _child.cleanValue = 100; } } else if ([keyPath isEqualToString:@"happyValue"]) { NSNumber *newValue = change[@"new"]; if ([newValue integerValue] < 90) { //保姆针对小孩脏了事件的处理代码 NSLog(@"保姆逗小孩开心"); _child.happyValue = 100; } } //用KVO也实现了小孩和保姆之间的通信,小孩可以脱离保姆而存在,进行解耦合,如果想换一个照顾小孩的类,只要在类中添加观察者,并且实现观察者方法就可以。 } - (void)dealloc { //在保姆对象被释放之前,要移除观察者。ARC无法帮我们完成。 [_child removeObserver:self forKeyPath:@"cleanValue"]; [_child removeObserver:self forKeyPath:@"happtValue"]; } @end
标签:
原文地址:http://blog.csdn.net/lerryteng/article/details/51360323