阅读 119

KVO和KVC

KVO

原理:当监听一个类的属性变化时,runtime在运行时,会动态生成一个名为NSKVONotifying_xx的子类,将原先类的isa指向NSKVONotifying_xx

@implementation NSKVONotifying_xx

- (void)setAge:(int)age {
    _NSSetIntValueAndNotify();
}

// 屏幕内部实现,隐藏了NSKVONotifying_MJPerson类的存在
- (Class)class {
    return [MJPerson class];
}

- (void)dealloc {
    // 收尾工作
}

- (BOOL)_isKVOA {
    return YES;
}

@end
复制代码

NSKVONotifying_xx重写了setKey方法,在属性设置时,调用以下方法:

- (void)willChangeValueForKey:(NSString *)key

- (void)didChangeValueForKey:(NSString *)key
复制代码

KVO只能监听实例变量的值变化,不能监听成员变量的值变化

KVC

// 给对象属性设值
- (void)setValue:(nullable id)value forKey:(NSString *)key
// 可以给对象属性的变量设值,如:[xx valueForKey:@"cat.age"]
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath

- (nullable id)valueForKey:(NSString *)key
- (nullable id)valueForKeyPath:(NSString *)keyPath
复制代码

setValue:forKey:方法流程

  1. 先顺序查找setKey_setKey方法,找到了则调用
  2. 如果没有找到,则调用+ (BOOL)accessInstanceVariablesDirectly
  3. 返回YES时,则按照_key_isKeykeyisKey顺序查找成员变量,并设值

valueForKey:方法流程

  1. 先顺序查找getKeykeyisKey_key方法,找到了则调用
  2. 如果没有找到,则调用+ (BOOL)accessInstanceVariablesDirectly
  3. 返回YES时,则按照_key_isKeykeyisKey顺序查找成员变量,并获取值

知识点:KVO设值会触发KVC监听

文章分类
iOS
文章标签