美文网首页
Category相关

Category相关

作者: 牛奶红茶 | 来源:发表于2021-03-01 16:55 被阅读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(策略)

    ---

    相关文章

      网友评论

          本文标题:Category相关

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