+load和+initialize

iOS开发面试时经常被问到,+load方法和+initialize方法。今天主要用源码分析下各自的调用机制。

+load方法

当APP启动的时候,dyld便会开始加载库和链接库。load_images这个函数便会执行,这个函数就会执行+load方法。

图一

这里边有两个重要的函数:prepare_load_methodscall_load_methods,一个是准备load方法,一个是调用load方法。

1.prepare_load_methods方法

图二

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

1.获取类的load表
图三

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

图五

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

2.call_load_methods方法

图六

call_load_methods函数可以看到,先执行了类的load方法调用,然后才执行了分类的load方法调用。

3.+load方法总结

  1. +load方法在mian函数之前调用,因为dyld完成之后才会到main函数。
  2. 自动调用且由系统统一调用。
  3. 执行顺序:先是父类,然后是子类,最后才是分类。

+initialize方法

图七

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

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

图十

图十一

图十二

  1. 递归的查找父类,直到NSObject类。
  2. +initialize方法只能被调用一次。
  3. 调用顺序:
  • 父类有子类都有分类:先是父类的分类,再是子类的分类
  • 父类没有分类子类有分类:先是父类,再是子类的分类
  • 父类有分类子类没有:先是父类的分类,再是子类
  • 父类子类都没有:先是父类,再是子类。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容