KVO和KVC

作者: love断鸿 | 来源:发表于2021-05-10 15:22 被阅读0次

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 这两个方法

相关文章

网友评论

      本文标题:KVO和KVC

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