美文网首页
Objective-C的本质(5)——Category原理

Objective-C的本质(5)——Category原理

作者: yangfei02821 | 来源:发表于2020-04-26 17:32 被阅读0次

参考:
iOS-Category原理
iOS底层原理总结 - Category的本质

1、load能继承吗

  • 可以继承,需要你主动调用,实际是通过objc_msgSend来调用,那就跟普通方法一样了。
  • 调用子类的load方法之前,会先调用父类的load方法
  • 主动调用load方法,最终调用的是最后参与编译的分类的方法,
  • 原因:合并时将最后参与编译的分类放在大数组前面,所以会优先调用。

2、添加分类类方法源码实现

运行时会通过类的一个方法isMetaClass来判断是否为元类,然后通过category一个方法methodsForMeta来获取对应的方法列表,最后添加到大数组当中。

3、load、initialize方法的区别什么?

1.调用方式
1> load是根据函数地址直接调用
2> initialize是通过objc_msgSend调用,只要是通过消息机制,就是通过isa找到对应的对象,先查看分类里面有没有,没有在找类方法中的,如果都没有再去父类中查找,也是先查看分类中有么有,在查看类方法中有没有

2.调用时刻
1> load是runtime加载类、分类的时候调用(只会调用1次)
2> initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次(父类的initialize方法可能会被调用多次)

3、load、initialize的调用顺序?
1.load
1> 先调用类的load
a) 先编译的类,优先调用load
b) 调用子类的load之前,会先调用父类的load
2> 再调用分类的load
a) 先编译的分类,优先调用load
2.initialize
1> 先初始化父类
2> 再初始化子类(可能最终调用的是父类的initialize方法)

4、父类实现了,子类没有实现
load:子类不调用父类load方法
initialize:子类调用父类的initialize方法

5、调用个数
initialize:
类只会调用同一个initialize方法,为最后参与编译的分类中的initialize方法
load:
类和类别都分别有load方法,都会调用。

4、分类形成过程

编写出一个分类就会生成一个category_t结构体,运行时的时候会将所有分类按照编译顺序合并成一个大数组,然后从后往前取出方法,保存在一个方法数组中,最后添加到类对象或元类对象方法列表中,添加过程为,将原有方法向后移动,然后将新的方法列表拷贝到数组前面。

5、objc_msgSend源码查看

objc_msgSend是汇编代码,所以可以通过class_getInstanceMethod方法间接的查看objc_msgSend的调用,里边有判断如果没有调用过initialize,就会调用_class_initialize,里边还有一个判断,如果有父类,并且父类又没调用initialize,那就父类递归调用_class_initializ,最后调用callInitialize,那就是通过消息机制,调用initialize方法了。

6、Load方法调用

Load方法,load_images,做前期准备,先将类按照父类,子类将load方法放在数组中,然后将分类的load方法放在数组,然后先加载类的数组load在加载分类的数组load。

7、分类可以添加属性吗?成员变量呢?

分类可以添加属性,底层结构也有属性数组,
属性写分类中,只会生成set和get方法的一个声明
直接添加成员变量、set和get方法,编译会报错,实例变量不能放在类别
但是可以间接添加成员变量

8、分类为什么不可以添加成员变量,自己模拟添加成员变量方法?

分类结构体没有数组来存放成员变量的,
通过之前对对象的分析我们知道成员变量是存放一个只读的结构体class_ro_t*ro当中,并且在编译的那一刻就已经决定好了。而分类是在运行时才去加载的。那么我们就无法再程序运行时将分类的成员变量中添加到这个的结构体中。因此分类中不可以直接添加成员变量。
1.类给对象赋值,存储在person2对象内部,赋值给成员变量
2.分类给对象赋值,存在全局的字典对象里面。
使用字典明显问题:
1字典一直在内存中,可能导致内存泄漏
2线程安全,同时访问,抢夺资源,添加多线程管理,加锁。
3添加属性都需要增加保存的全局字典

9、关联对象的原理

  • 关联对象并不是存储在被关联对象本身内存中
  • 关联对象存储在全局的统一的一个AssociationsManager中


    关联对象的原理

10、如何删除一个类单独key的关联对象

设置(赋值)关联对象为nil,就相当于是移除关联对象

11、关联对象没有weak的策略,ObjcAssociation中的value是强引用

12、对象释放,关联对象是否移除map中所有东西

会移除

相关文章

网友评论

      本文标题:Objective-C的本质(5)——Category原理

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