load和initialize方法

前言

我们将3个类A、B、C分别表示为父类、子类、子类的分类来了解load和initialize

注意:
1.下文中所说的类都是直接或者间接继承NSObject
2.这里只分析的类中实现+load和+initialize方法的情况,不包含主动调用

使用场景

  • +load方法通常用来进行Method Swizzle

  • +initialize方法一般用于初始化全局变量或静态变量

调用时机

  • load方法会在mian函数之前调用,会循环调用所有类(包括分类)的 +load 方法

  • initialize的调用是在第一次主动使用当前类的时候

调用次数

  • load和initialize在类中只要实现都会调用一次(非super,非主动调用)

执行的顺序

  • +load方法:A -> B -> C ,即 父类 -> 子类 -> 分类

  • +initialize方法: A -> C ,即 父类 -> 分类

方法实现方式

  • +load使用函数内存地址的方式 (*load_method)(cls, SEL_load);

  • +initialize使用发送消息 objc_msgSend 的方式

子类和父类

  • load方法不会考虑对NSObject的继承,所有类实现load方法就会实现,没有也不会沿用父类方法

  • 子类不实现initialize方法,父类实现initialize方法,子类沿用父类的方法

比如 父类A 中分别实现+load、+initialize方法,子类B中不实现+load、+initialize方法
执行的顺序 [A load] -> [A initialize] -> [A initialize]

类和类别

  • 本类和类别的+load方法存在就实现,不存在就不实现

  • 类别中的+initialize方法会覆盖本类的方法,只执行一个类别的+initialize方法

安全性

  • load和initialize方法内部使用了锁,所以都是线程安全的

其他注意点

  1. 在方法中如果使用super,load执行的顺序和次数依旧保持不变,但是initialize的执行顺序和次数会变动,会调用多次,所以开发中尽量不要使用super

2.在A、B、C的其中两个类的+load方法中去都实现方法的替换操作,由于方法置换2次使置换失效,所以+load中替换等操作加上dispatch_once保持执行一次

3.不要去主动去调用load或者initialize方法,会失去他们调用的“唯一性”

4.load方法不会直接触发initialize的调用,但是不要再+load出现self等类方法的调用,会使initialize的方法提前出现,原因是使该类的第一条消息提前发生

你可能感兴趣的:(load和initialize方法)