关于Category的学习笔记

Category的加载处理过程

1.通过runtime动态将分类的方法合并到类对象元类对象中.
2.把所有Category方法属性协议数据,合并到一个大数组中。
3.后面参与编译的Category数据,会在数组的前面
4.将合并后的分类数据(方法、属性、协议),插入到类原来数据的前面

例子:

首先我们定义GYPersonGYPerson+Test1GYPerson+Test2
同时添加-(void)run;方法。

1.png

会调用哪个run方法?
这个取决于编译顺序。如上述加载过程4,最后参与编译的方法,会在大数组第一个,所以它一定不会触发GYPersonGYPerson+Test1GYPerson+Test2会触发谁,通过查看编译文件顺序可以得知,如图2
2.jpg

调换顺序,可触发不同分类中的方法。注意:就算把GYPerson移动到最后,也是无法触发GYPerson中的方法

Category与Class Extend的区别

扩展的内容在编译的时候就合并到类信息中,分类是通过Runtime再合并。

Category的Load方法

1.+load方法会在runtime加载分类时调用。
2.调用子类+load之前会先调用父类+load
3.每个分类+load,在程序运行过程中只调用一次
注意:+load比较特殊,一定是先调用类中load。在调用分类中的load。并且不会被分类替代。通过函数地址直接调用,所以无编译顺序说法

Category的initialize方法

1.在第一次接收到消息时调用。([GYPerson alloc]
之后alloc,都不会触发
2.先调用父类,在调用子类

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容