Category 的实现原理
Category 实际上是Category_t的结构体,在运行时,新添加的方法,都被以倒序插入到原有方法列表的最前面,所以不同的Category,添加同一个方法,执行的实际上是最后一个。
Category 在刚刚编译完的时候,和原来的类是分开的,只有在程序运行起来后,通过Runtime,Category 和原来的类,才会合并到一起。
isa 指针的理解
isa 等价于 is kind of
实例对象的isa指向类对象
类对象指向元类对象
元类对象的isa指向元类的基类
isa 有两种类型
纯指针,指向内存地址
NON_POINTER_ISA,除了内存地址,还存有其他信息。
runtime 如何实现weak属性?
weak 此特征表明该属性定义了一种【非拥有关系】。为这中属性设置新值时,设置方法既不持有新值,也不释放旧值。
runtime 对注册的类,会进行内存布局,从一个粗粒度的概念上来讲,这时候会有一个hash表,这是一个全局表,表中是用weak指向的对象内存地址作为key,用所有指向该对象的weak指针表作为value。当此对象的引用计数为0的时候会delloc,假如该对象内存地址是a,那么就会以a为key,在这个weak表中搜索,找到所有以a为键的weak对象,从而设置为nil。
runtime 如何实现weak属性具体流程大致分为3步:
1、初始化时,runtime会调用objc_initWeak函数,初始化一个新的weak指针,指向对象地址。
2、添加引用时:objc_initWeak函数会调用objc_storeWeak()函数,objc_storeWeak()的作用是更新指针指向(指针可能原来指向其他对象,这时候需要将该weak指针与旧对象接触绑定,会调用到weak_unregister_no_lock)如果指针指向的新对象非空,则创建对应的弱引用表,将weak指针与新对象进行绑定,会调用到weak_register_no_lock。在这个过程中,为了防止多线程中竞争冲突,会有一些锁的操作。
3、释放时:调用clearDeallocating函数,clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。