KVO

作者: 纳兰沫 | 来源:发表于2019-11-27 16:41 被阅读0次

    iOS用什么方式实现对一个对象的KVO

    - 利用Runtime API的动态特性 动态生成一个子类 并且让instance的isa指针指向这个全新的子类
    - 当修改instance对象的属性时 会调用Foundation的_NSSet*ValueAndNotify的函数
      a.调用willChangeValueForKey:
      b.父类原先的setter
      c.调用didChangeValueForKey: 
        内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法
    

    如何手动触发KVO

    手动调用willChangeValueForKey:和didChangeValueForKey:
    

    直接修改成员变量会触发KVO么?

    不会触发KVO
    

    KVO

    KVO的全称是Key-Value Observing 俗称"键值监听" 可以用于监听某个对象属性值的改变
    

    [self.person methodForSelector:@selector(selector)] 获取方法的具体实现

    _NSSet*ValueAndNotify的内部实现
    1.调用willChangeValueForKey:
    2.调用原来的setter实现
    3.调用didChangeValueForKey:
    didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法
    
    使用了KVO 会重写-(Class )class 和 -(void)dealloc 和 -(BOOL)_isKVOA方法
    

    NSKVONotifying_MJPerson 里面重写class方法 是为了隐藏真正的类对象NSKVONotifying_MJPerson 如果不重写class方法 那么就会往他的superclass里面寻找方法 直到在NSObject里面寻找到class方法 调用class方法 会返回真正的类对象名称

    获取类对象里面的对象方法
        unsigned int count;
        //获得方法数组
        Method *methods = class_copyMethodList(object_getClass(self.person),  &count);
        //存储方法名
        NSMutableString *methodNames = [NSMutableString string];
        
        //遍历所有的方法
        for (int i = 0; i < count; i++) {
            //获得方法
            Method method = methods[i];
            //获得方法名
            NSString *methodName = NSStringFromSelector(method_getName(method));
            //拼接方法名
            [methodNames appendString:methodName];
            [methodNames appendString:@", "];
        }
        //释放
        free(methods);
        //打印方法名
        NSLog(@"%@ %@",self.person1,methodNames);
    

    相关文章

      网友评论

          本文标题:KVO

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