iOS开发-load和initialize的介绍

来源:互联网 发布:个人职业规划 知乎 编辑:程序博客网 时间:2024/06/12 12:47

1.load方法

load方法在这个文件被程序装载时调用。只要是在Compile Sources中出现的文件总是会被装载,这与这个类是否被用到无关,因此load方法总是在main()函数之前调用。
如果一个类实现了load方法,在调用这个方法前会首先调用父类的load方法。而且这个过程是自动完成的,并不需要我们手动实现。
如果一个类没有实现load方法,那么就不会调用它父类的load方法,这一点与正常的类继承和方法调用不一样,需要额外注意一下。

苹果官方文档的解释

Invoked whenever a class or category is added to the Objective-C runtime;implement this method to perform class-specific behavior upon loading.

这个方法在类被添加进来的时候就会调用,也就是说程序在开始加载期间,这个方法就被调用.
load的加载时机:
子类的+load会在父类的+load方法之后执行;
而分类的load则会在主类的load方法之后执行;
不同类之间的load方法调用顺序是不确定的。

当类的加载是耗时或者需要消耗比较多的内存的时候,尽量不要在load方法里面做这些耗时的工作,因为这样会增加App的启动时间,降低用户的体验。
由于调用load方法时的环境很不安全,我们应该尽量减少load方法的逻辑。另一个原因是load方法是线程安全的,它内部使用了锁,所以我们应该避免线程阻塞在load方法中。

一个常见的使用场景是在load方法中实现Method Swizzle

2. initialize方法

苹果官方文档的解释

Initializes the class before it receives its first message.The runtime sends initialize to each class in a program just before the class, or any class thatinherits from it, is sent its first message from within the program. The runtime sends theinitialize message to classes in a thread-safe manner. Superclasses receive this message beforetheir subclasses. The superclass implementation may be called multiple times if subclasses do notimplement initialize—the runtime will call the inherited implementation—or if subclassesexplicitly call [super initialize]

这个方法会在类的第一个方法调用前被调用。首先会先调用父类的initialize方法,如果子类没有实现initialize方法,那么父类会多次触发这个方法,为了避免这种情况的发生,可以在实现的方法里面添加一个判断:

+ (void)initialize {    if (self == [ClassName self]) {     // ... do the initialization ...    }}

initialize其实可以被认为是延迟加载的方法,类加载的时候并不会执行这个方法,只有当类实例化的时候,或者类的第一个方法被调用的时候才会执行这个方法

3.category中的load和initialize

在category中load方法会等到实现类加载完自身的load方法后再执行category的load方法.
initialize则调用最后一个被加载完成的类的initialize的方法.

4 总结

  1. load和initialize方法都会在实例化对象之前调用,以main函数为分水岭,前者在main函数之前调用,后者在之后调用。这两个方法会被自动调用,不能手动调用它们。
  2. load和initialize方法都不用显示的调用父类的方法而是自动调用,即使子类没有initialize方法也会调用父类的方法,而load方法则不会调用父类。
  3. load方法通常用来进行Method Swizzle,initialize方法一般用于初始化全局变量或静态变量。
  4. load和initialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。