12.12 +(void)initialize方法详解

1.什么时候被调用

initialize在类第一次接收到消息时调用,也就是objc_msgSend()。

具体的调用过程如下:
initialize方法通过objc_msgSend()消息传递的机制调用
objc_msgSend()汇编编写的内部调用了 _class_lookupMethodAndLoadCache3函数,它只是简单调用了lookUpImpOrForward函数

调用lookUpImpOrForward函数,在这里进行判断,首先判断外部传参,initialize参数yes代表需要调用+(void)initialize,然后判断类是否已经调用过+(void)initialize方法。
image.png
image.png
满足条件后调用 _class_initialize方法,方法中会先判断它有没有父类,父类有没有调用+(void)initialize方法,如果父类没有调用过,则先递归调用父类的+(void)initialize方法。最后调用自己的+(void)initialize方法。调用方式是通过callInitialize函数,内部实际就是发送了一个调用+(void)initialize方法的消息。
image.png
因为最后+(void)initialize的调用时通过msgSend调用的,所以如果子类没实现,自然就调用了父类的实现。

2.能写super么?为什么

同load方法,可以用super调用,但是没有必要,并且也一样会使父类的initialize被多次执行

3.执行次数

一次,但是如果子类的initialize方法没有实现父类的initialize会多次执行
image.png

4.使用场景

initialize方法主要用来对一些不方便在编译期初始化的对象进行赋值。
image.png

initialize可以用于初始化全局变量或静态变量

5.分类(Category)中的initialize方法能覆盖本类中的initialize么?

会,因为initialize方法是在类第一次接受到消息时调用的,发送

load和initialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。