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:方法流程
- 先顺序查找
setKey、_setKey方法,找到了则调用 - 如果没有找到,则调用
+ (BOOL)accessInstanceVariablesDirectly - 返回YES时,则按照
_key、_isKey、key、isKey顺序查找成员变量,并设值
valueForKey:方法流程
- 先顺序查找
getKey、key、isKey、_key方法,找到了则调用 - 如果没有找到,则调用
+ (BOOL)accessInstanceVariablesDirectly - 返回YES时,则按照
_key、_isKey、key、isKey顺序查找成员变量,并获取值
知识点:KVO设值会触发KVC监听