首先,要弄明白这两个之间的本质区别,请看我之前的博客
06 iOS底层原理 - +load方法本质探究和07 iOS底层原理 - +initialize方法探究
这里只总结两者的区别:
一,调用时机:
- 普通类方法:类对象主动发起调用时,就会加载普通类方法;
- +load方法:runtime在加载类和分类的时候,就会加载+load方法,只调用一次;
- +initialize方法:在类第一次接收到消息时调用,只调用一次。
二,调用方式:
- 普通类方法:通过objc_msgSend方法给类发送消息,Class -> isa,isa->Meta-class,类方法列表->类方法/superclass->父类查找类方法;
- +load方法:遍历类方法列表找到函数地址,直接通过函数地址调用;
- +initialize方法:通过objc_msgSend方法给类发送消息,Class -> isa,isa->Meta-class,类方法列表->类方法/superclass->父类查找类方法。
三,调用顺序:
- 普通类方法:
a> 存在分类的情况下,先调用分类的方法(后编译的分类先调用),此时就会覆盖后边分类和类的方法调用;
b> 子类调用类方法,会调用子类的方法,如果子类没有重写父类的方法,则会通过superclass扎到父类,然后调用父类方法。 - +load方法:
a> 先调用类的load,先编译先调用,如果调用子类的load,会先调用父类的;
b> 在调用分类的,先编译先调用。 - +initialize方法:
a> 先调用父类的initialize,然后再调用子类的initialize(先初始化父类,再初始化子类,每个类只初始化一次),
如果子类没有实现initialize方法,调用后,会出现父类多次调用的情况;
b>存在分类且分类有实现+initialize的话,就会先调用后编译的分类的方法,后面的方法实现都会被覆盖,
如果分类没有实现+initialize的话,就会找到父类调用方法实现。