Category相关

2021-03-01  本文已影响0人  牛奶红茶

1.Category的实现原理?

Category的底层结构 分类的结构体(图2) 根据图2结构体生成的变量

->所有的分类结构体都是一样的

-通过runtime动态将分类的方法合并到类对象、元类对象中

->Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息

->在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)

2.Category(分类)和Extension(类扩展)的区别是什么?

注意:

1.分类是用于给原油类添加方法的,因为分类的结构体指针中没有属性列表,只有方法列表,所以<原则上它只能添加方法,不能添加属性(成员变量),实际上是可以通过其他方法添加属性>

2.分类中的可以写@property,但是不会生成setter/getter方法,也不会生成成员变量(编译时会报警告)

3.可以在分类中访问原有类中.h中生命的属性和方法

4.如果分类中有和原有类同名的方法,会优先调用分类中的方法,就是说会忽略原有类的方法,所以同名方法的调用优先级为分类->本类->父类,因此在开发中浸凉不要覆盖原有类

5.如果多的分类中都有和原有类中同名的方法,那么调用个该方法的时候执行谁有编译器决定,编译器会执行最后一个参与编译的分类中的方法

->Class Extension在编译的时候,它的数据就已经包含在类信息中

->Category是在运行时,才会将数据合并到类信息中

3.Category中有load方法吗?load方法是在什么时候调用?load方法能继承吗?

->有load方法,

->load方法事在runtime加载类,分类的时候调用,

->load方法可以继承,

部分转载自-https://juejin.cn/post/6844903936088866823

4.load,initialize方法的区别是什么?它们在category中的调用顺序?以及出现继承时它们之间的调用过程

区别:load是根据函数地址直接调用的,initialize是通过objc_msgSend调用

调用时刻

load-> load是runtime加载类,分类的时候调用(只会主动调用一次)(子类通过[super load]的时候走的是消息转发)

initialize-> initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次,(父类的initialize方法kennel会被调用多次)

load,initialize的调用顺序

load-> 先调用类的load(先编译的类,优先调用load,调用子类的load之前,会先调用父类的load),在调用分类的load,(先编译的分类,优先调用load)

initialize-> 先初始化父类,在初始化子类(可能最终调用的是父类的initialize(子类如果未实现该方法))

5.Category能否添加成员变量?如果可以,如何给Category添加成员变量?关联对象以什么形式进行存储?

不能直接给Category添加成员变量,但是可以间接实现Category有成员变量的效果(关联对象)

为什么分类不能添加属性

- 分类没有自己的isa指针

- 类最开始生成了很多基本属性,比如IvarList,MethodList

- 分类只会将自己的method attach到主类,并不会影响到主类的IvarList

- 实例变量没有setter和getter方法。也没有自己的isa指针

通过runtime中提供的关联对象相关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)

关联API对象参数说明

参数一:id object 给哪个对象添加属性

参数二:  const void *key 关联对象中属性值存取过程中对应唯一标识,根据key来设置和取值

参数三:id value 关联的值,也就是set方法传入的值给属性去保存

参数四:  objc_AssociationPolicy 策略,属性以什么形式保存

关联对象的原理

实现关联对象的核心对象有 AssociationsManager,AssocicationsHashMap,ObjectAssociationMap,ObjectAssociation

AssociationsManager 是一个全局的单例,其内部有一个AssocicationsHashMap的hashMap对象(可以看做字典)

AssocicationsHashMap 字典的key是传进来的object,value是ObjectAssociationMap对象(可看作字典)

ObjectAssociationMap 字典的key是传过来的key,value是ObjectAssociation

ObjectAssociation中存放着value(值)和policy(策略)

---

上一篇下一篇

猜你喜欢

热点阅读