1.讲一下对象,类对象,元类,跟元类结构体的组成以及他们是如何相关联的?为什么对象方法没有保存的对象结构体里,而是保存在类对象的结构体里?
对象的结构体里存放着isa指针以及成员变量,对象的isa 指向类对象。类对象的isa 指向元类对象。
类对象和元类的结构体有isa、superclass、cache、bits,bits里存放着class_rw_t的指针。
【对象方法没有保存在对象结构里,而是保存在类对象的结构体中】
答:对象方法是每个对象可以相互共用的,如果每个对象都存储一份方法列表,对内存来说是相当的浪费。由于isa 指针指向的类对象,当调用的时候,直接去类对象中查找就可以了,可以节约很多内存。
2.class_ro_t 、class_rw_t的区别?
答:class_ro_t 字面意思:只读;class_rw_t可读可写。这两个变量共同点都是存储类的属性、方法、协议等信息。
class_ro_t:还存储了类的成员变量而class_rw_t则没有,这也及时分类不能增加成员变量的原因。class_ro_t在编译期就确定了固定的值,在整个运行时都只可读不可写的状态,在运行时调用realizeClass方法将class_ro_t复制到class_rw_t上
3.分类和扩展的区别是什么?分类的结构体里面有哪些成员?
答:扩展在编译器决议,他伴随类的产生而产生,亦随之一起消亡。分类则不同,他是在运行期决议的,扩展可以添加实例变量,而分类是不能添加实例变量的
分类的结构体 category_t;结构如下
struct category_t {
const char *name; //类的名字(name)
classref_t cls;//类(cls)
struct method_list_t *instanceMethods;//category中所有给类添加的实例方法的列表(instanceMethods)
struct method_list_t *classMethods; //category中所有添加的类方法的列表(classMethods)
struct protocol_list_t *protocols; //category实现的所有协议的列表(protocols)
struct property_list_t *instanceProperties; //category中添加的所有属性(instanceProperties)备注:不会生成对应的setter、getter方法的实现,只是生成了setter、getter方法的声明
};
4.weak 的底层实现原理
weak的底层其实是runtime维护的一个weak表,用于存储指向某个对象的所有weak指针。weak 表其实是一个hash表,key是所指对象的地址,value 是weak指针的地址数组(这个地址的值是所指向对象指针的地址),参考下runtime 的源码(objc_weak)
1.weak 初始化时 :runtime会调用objc_initweak函数,初始化一个新的weak 指针指向对象的地址。
2.添加引用时:objc_initWeak 函数会调用objc_storeWeak()函数,objc_storeWeak指针的作用是更新指针指向,创建对应的弱引用表
3.释放时,调用clearDeallocation函数。clearDeallcating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组吧其中的数据设置为nil,最后吧这个entry从weak表中删除,最后清除对象的记录。