OC底层

作者: Coder_JdHo | 来源:发表于2020-12-16 10:19 被阅读0次

isa指针

isa:是一个Class 类型的指针。 每个实例对象有个isa的指针,他指向对象的类,而Class里也有个isa的指针, 指向meteClass(元类)。元类保存了类方法的列表。当类方法被调 用时,先会从本身查找类方法的实现,如果没有,元类会向他父类查找该方法。
同时注意的是:元类(meteClass)也是类,它也是对象。元类也有isa指针,它的isa指针最终指向的是一个根元类(root meteClass)。根元类的isa指针指向本身,这样形成了一个封闭的内循环。

KVC

KVC是键值编码,一种通过字符串间接访问对象的方式(即给属性赋值)

KVC的底层实现
当一个对象调用setValue方法时,方法内部会做以下操作:
1). 检查是否存在相应的key的set方法,如果存在,就调用set方法。
2). 如果set方法不存在,就会查找与key相同名称并且带下划线的成员变量,如果有,则直接给成员变量属性赋值。
3). 如果没有找到_key,就会查找相同名称的属性key,如果有就直接赋值。
4). 如果还没有找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。
这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。

KVO

KVO(key-Value-Observing):键值观察机制,他提供了观察某一属性变化的方法。

使用KVO分为三个步骤:
1.通过addObserver:forKeyPath:options:context:方法注册观察者,观察者可以接收keyPath属性的变化事件。
2.在观察者中实现observeValueForKeyPath:ofObject:change:context:方法,当keyPath属性发生改变后,KVO会回调这个方法来通知观察者。
3.当观察者不需要监听时,可以调用removeObserver:forKeyPath:方法将KVO移除。需要注意的是,调用removeObserver需要在观察者消失之前,否则会导致Crash。

KVO的底层实现
KVO是基于runtime机制实现。
1.当一个类的属性首次被监听的时候,会在运行阶段生成一个新的派生类,对应的isa指针也会指向新的派生类,在这个派生类中被监听的属性的setter方法会增加willChangeValueForKey和didlChangeValueForKey方法。
2.当属性改变时,会调用willChangeValueForKey记录旧的值,然后属性值改变,接着调用didChangeValueForKey,这时kvo的observeValueForKeyPath就会被调用,实现监听的效果。

手动触发kvo

[self willChangeValueForKey:@"balance"];
 _balance = theBalance;
[self didChangeValueForKey:@"balance"];

KVC会触发KVO吗
会,KVC的底层实现就是会先调用setter方法的。

访问并修改一个类的私有属性

1). 一种是通过KVC获取。
2). 通过runtime访问并修改私有属性。

消息转发

消息传递机制 objc_msgSend():接收者会根据isa指针找到接收者自己所属的类,然后在所属类的”方法列表“(method list)中从上向下遍历。如果能找到与选择子名称相符的方法,就根据IMP指针跳转到方法的实现代码,调用这个方法的实现。
如果找不到与选择子名称相符的方法,接收者会根据所属类的superClass指针,沿着类的继承体系继续向上查找(向父类查找),如果 能找到与名称相符的方法,就根据IMP指针跳转到方法的实现代码,调用这个方法的实现。
如果在继承体系中还是找不到与选择子相符的方法,此时就会执行消息转发操作。

消息转发(Message Forward):是Objective-C语言级别的特性,即Runtime的特性,也是Objective-C动态语言的特色之一。Objective-C Runtime会提供3次挽救的机会(准确的说是1次动态方法解析+2次消息转发;其中实例方法救3次,类方法救1次):

1、自己试下补锅(动态方法解析):+resolveInstanceMethod:(要处理类方法就是+resolveClassMethod:)
2、让别人来背锅:-forwardingTargetForSelector:
3、还是自己解决吧(包装成NSInvocation):-(void)forwardInvocation:(NSInvocation *)anInvocation

如果都没处理就会报异常然后程序崩溃,提示noRecognizeSelector,要让程序不崩溃的话可以在resolveInstanceMethod方法里添加统一的实现(里面使用到:class_addMethod:)

相关文章

  • iOS--OC底层原理文章汇总

    OC底层原理01—alloc + init + new原理OC底层原理02—内存对齐OC底层原理03— isa探究...

  • OC底层原理汇总

    OC底层原理(一).alloc实际调用流程分析OC底层原理(二).内存分配与内存对齐OC底层原理(三)、isa、对...

  • 2021 iOS底层提升计划

    iOS底层提升方案 下方学习大纲大家可以参考学习《OC底层、核心编程探索》专栏的索引。 OC底层探索 OC对象占用...

  • iOS - 对象内存分布

    [toc] 参考 对象内存分布 intro OC底层 我们平时编写的OC代码,底层实现其实都是C\C++代码 OC...

  • OC对象的本质

    一、OC对象的底层实现 OC 中的代码在底层实现,使用的是 C、C++,所以要研究 OC 中的类结构,可以将 OC...

  • OC底层原理探索文档汇总

    OC底层探索: 01-OC对象的底层分析[https://www.jianshu.com/p/953fcfddde...

  • OC对象底层的探索

    OC对象的底层分析 OC底层原理探索文档汇总[https://www.jianshu.com/p/04883ea4...

  • iOS底层 -- OC对象底层本质

    NSObject的底层实现 Student的底层实现 OC对象继承关系的底层实现

  • Swift进阶 学习大纲

    想了解OC底层原理,可查看? OC底层原理 学习大纲[https://www.jianshu.com/p/9e19...

  • iOS底层原理总结-- KVO/KVC的本质

    iOS底层原理总结--OC对象的本质(一) - 掘金 iOS底层原理总结--OC对象的本质(二) - 掘金 iOS...

网友评论

      本文标题:OC底层

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