关于Category的学习笔记
2019-03-30 本文已影响0人
GY1994
Category的加载处理过程
1.通过runtime动态将分类的方法合并到类对象、元类对象中.
2.把所有Category的方法、属性、协议数据,合并到一个大数组中。
3.后面参与编译的Category数据,会在数组的前面
4.将合并后的分类数据(方法、属性、协议),插入到类原来数据的前面
例子:
首先我们定义GYPerson、GYPerson+Test1、GYPerson+Test2。
同时添加-(void)run;方法。
1.png
会调用哪个
run方法?这个取决于
编译顺序。如上述加载过程4,最后参与编译的方法,会在大数组第一个,所以它一定不会触发GYPerson,GYPerson+Test1、GYPerson+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调用