KVO

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)