Category

作者: 阿凡提说AI | 来源:发表于2019-01-06 19:14 被阅读11次

一、Category的加载处理过程

1.通过Runtime加载某个类的所有Category数据

2.把所有Category的方法、属性、协议数据,合并到一个大数组中
后面参与编译的Category数据,会在数组的前面

3.将合并后的分类数据(方法、属性、协议),插入到类原来数据的前面

二、+load方法

+load方法会在runtime加载类、分类时调用

每个类、分类的+load,在程序运行过程中只调用一次

+load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用
调用顺序
1.先调用类的+load
按照编译先后顺序调用(先编译,先调用)
调用子类的+load之前会先调用父类的+load

2.再调用分类的+load
按照编译先后顺序调用(先编译,先调用)

三、+initialize方法

+initialize方法会在类第一次接收到消息时调用

调用顺序
先调用父类的+initialize,再调用子类的+initialize
(先初始化父类,再初始化子类,每个类只会初始化1次)

+initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点
如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
如果分类实现了+initialize,就覆盖类本身的+initialize调用

四、如何实现给分类“添加成员变量”?

默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现

关联对象提供了以下API

添加关联对象
void objc_setAssociatedObject(id object, const void * key,
                                id value, objc_AssociationPolicy policy)

获得关联对象
id objc_getAssociatedObject(id object, const void * key)

移除所有的关联对象
void objc_removeAssociatedObjects(id object)

使用属性名作为key

objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj, @"property");

objc_AssociationPolicy


屏幕快照 2019-01-06 下午7.13.22.png

相关文章

网友评论

      本文标题:Category

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