张东轩的博客

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

0%

Objective-C 中的load和initialize

load调用时机

在这个文件被程序装载时调用。

当我们启动程序时,参与了编译的类、分类都会被加载进内存,load方法就是在这个类被加载的时候调用的,这个过程与这个类是否被使用是无关的,只要是在Compile Sources中出现的文件总是会被装载。 load是在main之前进行调用。

load调用顺序

一个程序中如果所有的类、分类都实现了load方法,那么所有的load方法都会被调用。它们的执行顺序遵循以下规则:

先执行所有类的load方法,再执行所有分类的load方法。 执行类的load方法时,是按照参与编译的顺序,先编译的类先执行,但是如果某个类是继承自另一个类,那么会先执行父类的load方法个再执行自己的load方法。 执行分类的load方法时,是按照分类参与编译的顺序,先编译的分类先执行。

编译顺序是按照项目中Build Phases --> Compile Sources文件排序来进行的,最上面的就最先编译。

initialize调用时机

initialize方法是在类或它的子类收到第一条消息时被调用的,这里的消息就是指实例方法或类方法的调用,所以所有类的initialize调用是在执行main函数之后调用的。而且一个类只会调用一次initialize方法。如果一个类在程序运行过程中一直没有被使用过,那这个类的initialize方法也就不会被调用,这一点和load方法是不一样的。

使用initialize要比使用load安全(因为在调用initialize时所有类已经被加载进内存了),但我们还是要尽量少用initialize这个方法个,尤其要谨慎在分类中实现initialize方法,因为如果在分类中实现了,本类实现的initialize方法将不会被调用。实际开发中initialize方法一般用于初始化全局变量或静态变量。

应用场景

load方法通常用来进行Method Swizzleinitialize方法一般用于初始化全局变量或静态变量,loadinitialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。

参考 https://juejin.cn/post/6844904040703197191