MJiOS底层笔记--KVO本质

本文属笔记性质,主要针对自己理解不太透彻的地方进行记录。

推荐系统直接学习小码哥iOS底层原理班---MJ老师的课确实不错,强推一波。


NSKVONotifying_Person

KVO时,将被监听的对象isa指针动态修改成新类NSKVONotifying_Person

在对一个(Person)instance对象使用KVO进行监听时,系统利用RuntimeAPI动态生成一个(Person的)子类,并且让(Person)instance对象的isa指向这个全新的子类


NSKVONotifying_Person内部

  • isa

指向NSKVONotifying_Person内部元类,提供方法实现

  • superClass、class

为了掩盖NSKVONotifying_Person的存在,修改了这两个方法。使其结果与Person类返回的相同。

Class cls = object_getClass(self.person1);
Class spcls =class_getSuperclass(cls);
NSLog(@"object_getClass==%@",cls);
NSLog(@"class==%@",[self.person1 class]);
NSLog(@"class_getSuperclass==%@",spcls);
NSLog(@"superclass==%@",[self.person1 superclass]);

//打印
object_getClass==NSKVONotifying_MJPerson
class==MJPerson
class_getSuperclass==MJPerson
superclass==NSObject
复制代码
  • dealloc

做一些收尾工作

  • isKVOA

鉴定是否被KVO


_NSSetXXXValueAndNotify

被监听对象属性的set方法IMP指针所指方法

Foundation下的一个C语言函数,当调用被监听对象属性的set方法时,实际上将会调用这个C语言方法。

其内部将会调用一系列方法修改成员变量并且触发监

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

// 伪代码
void _NSSetIntValueAndNotify()
{
    [self willChangeValueForKey:@"age"];
    [super setAge:age];
    [self didChangeValueForKey:@"age"];
}
复制代码

willChangeValueForKey && didChangeValueForKey

触发监听的方法。可以手动调用以主动触发监听

  • 只有被监听的属性被修改,才会调用这个方法

未被监听的属性修改不会触发

  • 两个方法需要配对使用

只调用didChangeValueForKey不会触发监听


KVO触发条件

通过set方法为属性赋值

直接修改成员变量不会触发监听

KVC与KVO

KVC赋值是可以触发KVO的

并且,KVC内部实现了通知逻辑(willChangeValueForKey&&didChangeValueForKey)。即使没有实现set方法,也能被通知。

KVC赋值过程

其中accessInstanceVariablesDirectly默认返回YES

KVC取值过程

其中accessInstanceVariablesDirectly默认返回YES

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值