当项目中有多个KVO

当项目中有多个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 for the key path "text" from 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 *)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              // 添加监听时传来的值

你可能感兴趣的:(当项目中有多个KVO)