KVO

作者: 鐧箪 | 来源:发表于2019-07-08 09:37 被阅读0次

    KVO Key-Value Observing 典型的观察者模式承载者。基于监控键值发生变化,通知观察者。
    KVO 就是基于 KVC 实现的关键技术之一

    KVO基于runtime 观察一个类的属性(Animal 有个属性 kind) 当属性发生变化的时候 系统会自动生成一个类 继承当前类 NSKVONotifying_Animal 在这个类重写当前属性的set方法 setKind 调用 [super setKind:kind] [self willChangeValueForKey:@"kind"] 和 [self didChangeValueForKey:@"kind"]

    系统默认自动通知 如果需要手动通知

     + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key  
    {  
        //当这两个值改变时,使用自动通知已注册过的观察者,观察者需要实现observeValueForKeyPath:ofObject:change:context:方法  
        if ([key isEqualToString:@"kind"])  
        {  
            return NO;  
        }  
        return [super automaticallyNotifiesObserversForKey:key];  
    } 
    
    在需要改变的地方 
    [self willChangeValueForKey:@"kind"]; 
    self.animal.kind = @"pander";
    [self didChangeValueForKey:@"kind"];
    

    KVO动态改变指针指向 我们也可以手动创建KVO

    动物类
    @interface Animal : NSObject
    @property(nonatomic, strong) NSString *kind;
    @end
    
    添加NSObject类目
    @interface NSObject (KVO)
    - (void)animaladdObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
    @end
    
    
    NSString *const ObserverKey = @"ObserverKey";
    @implementation NSObject (KVO)
    
    // 仿系统的, 前缀是为了区别系统的
    - (void)animaladdObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context
    {
    // 把观察者保存到当前对象
       objc_setAssociatedObject(self, (__bridge const void *)(ObserverKey), observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    // 修改对象isa指针
    object_setClass(self, [AutoNSKVONotifying_Animal class]);
    }
    

    动态改变指针指向子类

    extern NSString *const ObserverKey;
    @implementation AutoNSKVONotifying_Animal
    - (void)setKind:(NSString *)kind
    {
     [super setKind:kind];
    // 获取观察者
     id obsetver = objc_getAssociatedObject(self, ObserverKey);
    
     [obsetver observeValueForKeyPath:@"kind" ofObject:self change:nil context:nil];
     }
    @end
    
    @property(nonatomic,strong)Animal * animal;
    
    self.animal = [[Animal alloc] init];
        [self.animal animaladdObserver:self forKeyPath:@"kind" options:NSKeyValueObservingOptionNew context:nil];
    
    self.animal.kind = @"tiger";
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
       NSLog(@"%@, %@", keyPath, self.animal.kind);
      }
    

    相关文章

      网友评论

          本文标题:KVO

          本文链接:https://www.haomeiwen.com/subject/ntuphctx.html