10.17 KVO键值观察 和 NSNotificationCenter通知中心类 笔记
一、KVO(key-Value Observe)键值观察 可以让一个对象指定一个观察者,该观察者将观察该对象中某些指定的属性或实例变量的值的变化情况,并处理这些值的变化。在 UI 中常常很多控件之间是相关的,一个控件的某个状态的更改 会牵连 其他某些控件的状态的更改,以前我们是用委托和协议来实现,有了KVO之后,控件之间的状态的牵连改变也可以用KVO来实现。
1. 设置观察者 和 被观察的属性或实例变量
[stu addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:NULL];
这里 stu 是一个自定义的Student对象,该对象有一个age属性,self是任意一个类对象observe,表示是该age属性的一个观察者,该observe对象需要实现 observeValueForKeyPath: ofObject: change: context: 方法用来处理该age属性值发生变化时要进行的行为。 options参数表示该age属性值发生变化时的一些处理选项,这个选项直接影响 下面方法的 change参数表示的字典中包含的内容。 context是任意一个C语言指针类型,用于添加额外的参数。
2. 观察者observe对象需实现下面的处理方法,处理所观察的属性的值变化是要进行的行为;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary *)change context:(void *)context
{
NSLog(@"--%@", change);
}
上面的keyPath参数便是observe对象当初所指定观察的属性或实例变量, object参数表示observe当前正在观察的属性或实例变量 属于哪个对象, change字典对象中的内容由上面的options参数决定。context参数和当时设置观察者时提供的context参数时同一个。
3. 关于options参数:其值有下面几个,可以按位或“ | ” 起来。
1》 NSKeyValueObservingOptionNew: 表示change字典中将含有被观察属性此次变化后的新值。
2》 NSKeyValueObservingOptionOld:表示change字典中将含有被观察属性此次变化前的值。
3》 NSKeyValueObservingOptionInitial:表示立刻给观察者observe发送一条通知,这一条通知也会触发调用上面observe对象中实现的 observeValueForKeyPath: ofObject: change: context: 方法,如果此时同时指定了NSKeyValueObservingOptionNew选项,此时这条通知里面的change中将包含一个保存了被观察属性的当前值的键值对,键名为New。 但是即使此时也同时指定了NSKeyValueObservingOptionOld,change中也不会包含该被观察属性前一次的值。 而且发现,这条通知还会调用一次被观察属性 所在类 的 initialize方法一次。
4. 如果观察者不想观察一个属性的变化情况了,可以移除观察者与属性之间的关系
[stu removeObserver: observe forKeyPath:@"age" ];
上面表示observe对象不再观察stu的属性age的变化了。注意,在观察者(这里是observe)或属性拥有者( 这里是 stu)销毁之前,一定要记得将观察者与其所观察的属性之间的关系用上面方式移除,否则可能会出现bug。
5. ReactiveCocoa框架就是用KVC 和KVO写成的。可以去尝试一下;
二、NSNotificationCenter 通知中心类
和KVO类似,该类也是用来发送通知,但是它可以发送任何通知,而不是局限于属性和实例变量。 它的通知是以字符串来匹配的,一个通知可以有多个接收者。 NSNotificationCenter类是一个单例类,通过defaultCenter来创建这个唯一的实例。它可以很方便的用于在两个不相关的类之间传递信息。
1. 给一个指定通知注册一个观察者。用指定的方法来处理这个通知。通知是用字符串来匹配的。同时还可以指定该观察者只观察谁发送的的通知。object为nil的话表示观者所有对象发送的该通知。
[ [NSNotificationCenter defaultCenter] addObserver:<#(id)#> selector:<#(SEL)#> name:<#(NSString *)#> object:<#(id)#>]
observer参数指定的是name参数表示的通知的接收者,selctor参数是观察者observe对象中自定义实现的方法,用来接收通知,并做一些处理动作,该方法有一个参数,为 (NSNotification *)类型,对应接收的通知。object 参数表示该观察者只从object指定的对象接收 name表示的通知。
2. 发送一个指定的通知,同时指定发送该通知的对象是谁,以及通知的内容。
[ [ NSNotificationCenter defaultCenter] postNotificationName:<#(NSString *)#> object:<#(id)#> userInfo:<#(NSDictionary *)#>]
name参数表示通知名,object表示发送该通知的对象,相当于寄件人;userInfo表示通知内容,是一个字典对象。
3. 在观者者对象销毁前,一定记得将其所有观察的通知都移除掉。
[ [ NSNotificationCenter defaultCenter] removeObserver:<#(id)#>];
将指定的观察者移除,这时,这个指定的观察者将不再观察任何通知
4.让指定的观察者不再观察来自指定对象object发送的通知name。
[ [ NSNotificationCenter defaultCenter] removeObserver:<#(id)#> name:<#(NSString *)#> object:<#(id)#>];

浙公网安备 33010602011771号