A1_Runtime运行时

2020-06-03  本文已影响0人  求长生

一、objc 对象的 isa 的指针指向什么?有什么作用?
1.isa:是一个Class 类型的指针. 每个实例对象有个isa的指针,他指向对象的类,而Class里也有个isa的指针, 指向metaClass(元类)。
2.Root class (class)其实就是 NSObject,NSObject 是没有超类的。
3.每个 Class 都有一个 isa 指针指向唯一的 Meta class。
4.每个 Meta class 的 isa 指针都指向 Root class (meta)。
isa 等价于 is kind of
 实例对象 isa 指向类对象
 类对象指 isa 向元类对象
 元类对象的 isa 指向元类的基类
isa 有两种类型
 纯指针,指向内存地址
 NON_POINTER_ISA,除了内存地址,还存有一些其他信息

二、一个 NSObject 对象占用多少内存空间?
一个 NSObject 对象都会分配 16byte 的内存空间。实际上在 64 位 下,只使用了 8byte;

三、对 class_rw_t 和 class_ro_t 的理解?
每个类都对应有一个class_ro_t结构体和一个class_rw_t结构体。在编译期间,class_ro_t结构体就已经确定。在runtime运行之后,具体说来是在运行runtime的realizeClass 方法时,会生成class_rw_t结构体,该结构体包含了class_ro_t,并且更新data部分,换成class_rw_t结构体的地址。
https://www.jianshu.com/p/823eaedb3697
class_ro_t存储了当前类在编译期就已经确定的属性、方法以及遵循的协议。
class_rw_t在运行时,ObjC 类中的属性、方法还有遵循的协议等信息都保存在 class_rw_t 中。

四、runtime的应用
1.拦截系统自带的方法调用(Method Swizzling黑魔法)
2.给分类增加属性
3.替换已有的OC方法。

五、Runtime 的方法缓存?存储的形式、数据结构以及查找的过程?
cache_t增量扩展的哈希表结构。哈希表内部存储的 bucket_t。
bucket_t 中存储的是 SEL 和 IMP的键值对。
如果是有序方法列表,采用二分查找
如果是无序方法列表,直接遍历查找

// 缓存曾经调用过的方法,提高查找速率
struct cache_t {
struct bucket_t *_buckets; // 散列表
mask_t _mask; //散列表的长度 - 1
mask_t _occupied; // 已经缓存的方法数量,散列表的长度使大于已经缓存的数量的。
//...
}

struct bucket_t {
cache_key_t _key; //SEL作为Key @selector()
IMP _imp; // 函数的内存地址
//...
}

六、方法交换method swizzling(黑魔法)
Objective-C 中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是 selector 的名字。 利用 Objective-C 的动态特性,可以实现在运行时偷换 selector 对应的方法实现。
1.利用 method_exchangeImplementations 交换两个方法的实现。
2.利用 class_replaceMethod 替换方法的实现。
3.利用 method_setImplementation 来直接设置某个方法的 IMP。

上一篇下一篇

猜你喜欢

热点阅读