當項目中有多個KVO,且觀察的屬性一致的時候,用context 來區(qū)分開來
如果是單個通知的 在 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 里的各個參數(shù)
- (void)observeValueForKeyPath:(NSString *)keyPath // 監(jiān)聽的屬性名稱
ofObject:(id)object // 被監(jiān)聽的對象
change:(NSDictionary *)change // 屬性的值
context:(void *)context // 添加監(jiān)聽時傳來的值