+load
+load 方法是当类或分类被添加到 Objective-C runtime 时被调用的,实现这个方法可以在类加载的时候执行一些类相关的行为。子类的 +load 方法会在它的所有父类的 +load 方法之后执行,而分类的 +load 方法会在它的主类的 +load 方法之后执行。但是不同的类之间的 +load 方法的调用顺序是不确定
子类、父类和分类中的 +load 方法的实现是被区别对待的。也就是说如果子类没有实现 +load 方法,那么当它被加载时 runtime 是不会去调用父类的 +load 方法的。同理,当一个类和它的分类都实现了 +load 方法时,两个方法都会被调用
+initialize
+initialize 方法是在类或它的子类收到第一条消息之前被调用的,这里所指的消息包括实例方法和类方法的调用。也就是说 +initialize 方法是以懒加载的方式被调用的,如果程序一直没有给某个类或它的子类发送消息,那么这个类的 +initialize 方法是永远不会被调用的。目的:节省系统资源,避免浪费
runtime 使用了发送消息 objc_msgSend 的方式对 +initialize 方法进行调用。也就是说 +initialize 方法的调用与普通方法的调用是一样的,走的都是发送消息的流程。换言之,如果子类没有实现 +initialize 方法,那么继承自父类的实现会被调用;如果一个类的分类实现了 +initialize 方法,那么就会对这个类中的实现造成覆盖。
一个子类没有实现 +initialize 方法,那么父类的实现是会被执行多次的,想确保 +initialize 方法只执行一次,避免多次执行:
+ (void)initialize {
if (self == [ClassName self]) {
// ... do the initialization ...
}
}
| +load | +initialize | |
|---|---|---|
| 调用时机 | 被添加到runtime时 | 收到第一条消息时 |
| 调用顺序 | 父类->子类->分类 | 父类->(分类覆盖)->子类 |
| 调用次数 | 1次 | 多次 |
| 是否需要显示调用父类方法 | 否 | 否 |
| 是否沿用父类的实现 | 否 | 是 |
| 分类中的实现 | 类和分类都执行 | 覆盖类中的方法只执行分类的实现 |