1.+(void)load
load方法在runtime加载类、分类的时候调用,不管是否使用了这个类,都会调用load方法,并且在程序运行过程中只调用一次,
1>load方法也会随着Category合并到元类中的方法列表中,所以如果手动调用load方法也是遵循obj
c_msgSend消息发送机制的比如[NSPerson load],如果没有实现,会调用父类的load方法实现。
2>加载的时候调用load方法不遵循消息发送机制,而是直接找到方法的地址调用的,所以类和分类中有load方法的实现在加载的时候都会调用。
/*--------------------------------------------load方法的调用顺序--------------------------------------------------------*/
1>先调用类的+load
- 按照编译先后顺序调用(先编译,先调用)
- 调用子类的+load之前会先调用父类的+load
2>再调用分类的+load
- 按照编译先后顺序调用(先编译,先调用)
为什么子类会先调用父类的load呢?
因为底层执行的call_alss_loads方法中,有一个superclass的递归调用
2.+(void)initialize
+initialize方法会在类第一次接收到消息时调用,比如[NSObject alloc]就会调用initialize方法
/*--------------------------------------------initialize方法的调用顺序--------------------------------------------------------*/
先调用父类的initialize,再调用子类的initialize,每个类只会初始化1次
initialize与load的区别是,initialize通过objc_msgSend进行调用,所以如果子类没有实现initialize,会调用父类的initialize,如果分类实现了initialize,就会覆盖类本身的initialize调用。
但是,正常的objc_msgSend调用只会执行一次,比如[Person test],只会执行Person的test或者父类test中的一个,initialize会向上触发父类执行initialize方法。比如调用[Person initialize],如果NSObject还没有执行initialize方法,那么这时候就会调用[NSObject initialize]。这事因为objc_msgSend发送消息的参数中有一个bool initialize参数,如果NO,就先递归查找父类的初始化情况,如果父类也为NO,那么先初始化父类,再初始化自己。