load与initialize

2021-06-28  本文已影响0人  Johnny_Wu

一、load

load的方法调用是在加载类的时候,是通过函数的指针直接调用的,不是通过obj_msgSend消息发送机制,所以不存在查找的过程。
因为是通过函数指针直接调动,所以正常情况下,所有实现了load方法的类都会被调用load方法。

调用顺序如下: 截屏2021-06-26 下午4.40.47.png

二、initialize

类第一次接受到消息的时候调用。因为走的是消息机制(objc_msgSend)。根据消息机制的查找机制,先找到的是分类的方法,调用的是分类的initialize。正常情况下,每个类的initialize只会调用一次。

下面我们看一种情况:
MJPerson为MJStudent的父类,MJPerson实现了initialize方法,MJStudent未实现initialize方法。此时调用[[MJStudent alloc] init]。会发生什么情况。
结果为父类MJPerson的initialize被调用了两次。为什么呢?

要理解这个问题,得去看源码,我抽取了伪代码如下: 截屏2021-06-26 下午4.42.31.png
根据这个伪代码,答案很明确了。[[MJStudent alloc] init]的时候,发现MJStudent没有初始化,接着发现MJPerson也没初始化,会先去初始化MJPerson,通过objc_msgSend调用MJPerson的initialize方法。接着再调用自己的initialize方法,因为MJStudent没有实现initialize方法,根据objc_msgSend的机制,会去父类MJPerson找initialize,因为MJPerson类实现了initialize方法,所以就再一次调用了MJPerson的initialize方法。

三、总结

截屏2021-06-26 下午5.04.24.png
截屏2021-06-26 下午5.04.44.png

最重要的一点:
load是通过指针直接调用的,所以可以所有类的load都可以被调用,其实load就是要达到这个目的。
initialize是通过objc_msgSend调用的,根据objc_msgSend的调用原理,一个类(分类)实现了多个initialize,那么只有一个initialize被调用。

上一篇下一篇

猜你喜欢

热点阅读