OC底层那些事

2020-01-25  本文已影响0人  CS_SDN

1. Runtime是什么?

runtime是由C和C++汇编实现的一套API,为OC语言加入了面向对象,运行时的功能

运行时(Runtime)是指将数据类型的确定由编译时推迟到了运行时
eg: extension - category 的区别
联想到:运行时主要体现在平时的rw中

编译时只读取到了ro,但是其中真正的方法读取主要体现在rw,
例如:编译好的内存还可以往其中添加编译和属性,ro是无法修改的

平时编写的OC代码,在程序运行过程中,其实最终会转换成Runtime的C语言代码,Runtime是Object-C的幕后工作者

runtime的应用:


runtime的应用

2.方法的本质,sel是什么?IMP是什么?两者之间的关系又是什么?

⽅法的本质:发送消息,消息会有以下⼏个流程
1:快速查找(objc_msgSend)~cache_t缓存消息
2:慢速查找-递归⾃⼰|⽗类~lookUpImpOrForward
3:查找不到消息:动态⽅法解析~resolveInstanceMethod
4:消息快速转发~forwardingTargetForSelector
5:消息慢速转发~methodSignatureForSelector&forwardInvocation

sel是⽅法编号~在read_images期间就编译进⼊了内存
imp就是我们函数实现指针,找imp就是找函数的过程
sel就相当于书本的⽬录tittle
imp就是书本的⻚码
查找具体的函数就是想看这本书⾥⾯具体篇章的内容
1:我们⾸先知道想看什么~tittle(sel)
2:根据⽬录对应的⻚码(imp)
3:翻到具体的内容

3.能否向编译后的得到的类中增加实例变量?能否想运⾏时创建的类中添加实例变量

答案:
1:不能向编译后的得到的类中增加实例变量
2:只要内没有注册到内存还是可以添加

原因:我们编译好的实例变量存储的位置在ro,⼀旦编译完成,内存结构就完全确定就无法修改

可以添加属性+⽅法

4.Asssociate⽅法关联的对象

Asssociate⽅法关联的对象

5.isKindOfClass和isMemberOfClass

isKindOfClass和isMemberOfClass

isKindOfClass和isMemberOfClass主要看清楚查找的⽅向

6.[self class]和[super class]的区别以及原理分析

[self class]就是发送消息objc_msgSend,消息接受者是self⽅法编号:class

[super class]本质就是objc_msgSendSuper,消息的接受者还是self方法编号:class

只是objc_msgSendSuper会更快直接跳过self的查找

7.Runtime是如何实现weak的,为什么可以⾃动置nil

流程图

1.通过SideTable找到我们的weak_table
2.weak_table根据referent找到或者创建weak_entry_t
3.然后append_referrer(entry,referrer)将我的新弱引⽤的对象加进去entry
4.最后weak_entry_insert 把entry加⼊到我们的weak_table

8.黑魔法MethodSwizzling的坑与应⽤

1.交换类主动调用load
解决办法:单例设计

2.交换没有自己没有实现,父类实现
解决办法:
A.会先尝试给自己添加要交换的方法
B.然后再将父类的IMP给swizzle

9.内存偏移面试

本文部分图层转载自Logic education Cooci

上一篇下一篇

猜你喜欢

热点阅读