美文网首页
+load和+initialize

+load和+initialize

作者: 好久不见_47b7 | 来源:发表于2020-03-11 17:40 被阅读0次

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. 调用顺序:
  • 父类有子类都有分类:先是父类的分类,再是子类的分类
  • 父类没有分类子类有分类:先是父类,再是子类的分类
  • 父类有分类子类没有:先是父类的分类,再是子类
  • 父类子类都没有:先是父类,再是子类。

相关文章

网友评论

      本文标题:+load和+initialize

      本文链接:https://www.haomeiwen.com/subject/ebrhjhtx.html