iOS开发面试时经常被问到,+load方法和+initialize方法。今天主要用源码分析下各自的调用机制。
+load方法
当APP启动的时候,dyld便会开始加载库和链接库。load_images
这个函数便会执行,这个函数就会执行+load方法。

这里边有两个重要的函数:
prepare_load_methods
和call_load_methods
,一个是准备load方法,一个是调用load方法。
1.prepare_load_methods方法

在准备load方法里边又分为获取类的load表和获取分类的load表。
1.获取类的load表


- 进入
schedule_class_load
函数,将会递归的找到父类一直到NSObject。 - 将重载load方法的类添加到
loadable_classes
这个表里,按从父类到子类的顺序。没有重载load方法的类忽略。
2.获取分类的load表

将所有重载load方法的分类加入到
loadable_categories
表里边,没有重载load方法的分类忽略。
2.call_load_methods方法

由
call_load_methods
函数可以看到,先执行了类的load方法调用,然后才执行了分类的load方法调用。
3.+load方法总结
- +load方法在mian函数之前调用,因为dyld完成之后才会到main函数。
- 自动调用且由系统统一调用。
- 执行顺序:先是父类,然后是子类,最后才是分类。
+initialize方法

给+initialize方法加入断点,可以很清楚的看到initialize方法是在main函数之后执行的,且是被动调用的,因为它走的是发送消息流程的流程。

当这个已经初始化且没有发送过initialize方法时,就会执行
_class_initialize
函数。这个函数有三个主要逻辑:如下四张图.



- 递归的查找父类,直到NSObject类。
- +initialize方法只能被调用一次。
- 调用顺序:
- 父类有子类都有分类:先是父类的分类,再是子类的分类
- 父类没有分类子类有分类:先是父类,再是子类的分类
- 父类有分类子类没有:先是父类的分类,再是子类
- 父类子类都没有:先是父类,再是子类。
网友评论