当项目中有多个KVO,且观察的属性一致的时候,用context 来区分开来
如果是单个通知的 在 delloc 里直接移除就可以了,并不会引起问题,但如果写入了多个之后,就会引起错误,具体错误提示见下面代码。
在.m 中写入
[_pingtai addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
[_isyyzz addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <Baodan 0x7f820a8bb600> for the key path "text" from <UITextField 0x7f820a428e70> because it is not registered as an observer.'
这个错误存在概率性,有时候能报错,而有时候又不报错。
因为在 addObserver 接收顺序是没有固定的。运气好就不会奔溃。
解决这一问题就是在addObserver 把 context 给加进去 代码如下
static NSString *pingtaiContext = @"pingtai";
static NSString *isyyzzContext = @"yyzz";
// 添加观察者 ,开启上下文
[_pingtai addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:(__bridge void * _Nullable)(pingtaiContext)];
[_isyyzz addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:(__bridge void * _Nullable)(isyyzzContext)];
#pragma mark 观察者 平台
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
NSString * string = [change objectForKey:@"new"];
NSLog(@"string =%@",string);
NSLog(@"context =%@",context);
if (context ==@"pingtai") {
NSLog(@"我选择了pingtai"); }
else if (context ==@"yyzz"){
NSLog(@"我选择了yyzz");
分析下 在addObserver 里的各个参数
- (void)observeValueForKeyPath:(NSString *)keyPath // 监听的属性名称
ofObject:(id)object // 被监听的对象
change:(NSDictionary *)change // 属性的值
context:(void *)context // 添加监听时传来的值