KVO
最近想重新充下电, 巩固下基础, 把以前学过的东西再重新整理一遍, 我是搬运工, 懂得都懂
Person类的某个属性添加了监听, person的实例变量的isa 会指向 NSKVONotifying_Person, NSKVONotifying_Person的superclass会指向 Person
NSKVONotifying_Person 类当中除了Person当中的变量 还有 dealloc _isKVOA
结论: 添加kvo 之后 系统会生成 Person的派生类 NSKVONotifying_Person, 并且会改变person实例的 isa指向, 从 指向 Person的类对象 变为 NSKVONotifying_Person的类对象. 在NSKVONotifying_Person的类对象中 重写父类Person的属性的set方法 在NSKVONotifying_Person的set方法中
- (void)setAge:(int)age {
[self willchangeValueForKey:@"age"];
父类set方法的实现
[self didChangeValueForKey];
}
NSKVONotifying_Person 的 isa是指向NSKVONotifying_Person的元类对象
KVC
KVC赋值
1: 先查找 setKey, _setKey
2: 没找到的话会访问 accessInstanceVariablesDirectly 得到一个BOOL值 result(默认是YES)
accessInstanceVariablesDirectly 的意思是, 是否允许访问成员变量
3: result = NO, 调用setValue:forUndefinedKey: 并抛出异常NSUnknownKeyException
4: result = YES, 则会继续查找 _key、_isKey、key、isKey
5: 找不到 调用setValue:forUndefinedKey: 并抛出异常NSUnknownKeyException
KVC取值
1: 先查找 getKey、key、 isKey、_key
2: 没找到的话会访问 accessInstanceVariablesDirectly 得到一个BOOL值 result(默认是YES)
3: result = NO, 调用valueForUndefinedKey: 并抛出异常NSUnknownKeyException
4: result = YES, 则会继续查找 _key、_isKey、key、isKey成员变量
5: 没找到的话会访问 accessInstanceVariablesDirectly 得到一个BOOL值 result(默认是YES)
备注
验证发现: didChangeValueForKey 这个方法 内部会检测 是否实现了willchangeValueForKey这个方法, 如果没有实现willchangeValueForKey,是不会触发kvo的
手动触发kvo的时候 必须要实现willchangeValueForKey 和 didChangeValueForKey
KVC会触发KVO监听, 无论访问的是 setKey, _setKey, _key、_isKey、key、isKey
原因:KVC内部 实现了 willchangeValueForKey和didChangeValueForKey 这两个方法
网友评论