type
status
date
slug
summary
tags
category
icon
password
本文是Objective-C系列的第5篇,主要讲述了及loadinitialize两个特殊方法的相关特性及其底层的实现。

一、常用知识点

在讲述之前,我们先把该两个方法常用到的一些知识点先列出。
notion image

二、+load

2.1 源码导读

根据下列顺序,阅读objc源码即可。
notion image

2.2 测试用例

测试用例源码在02-load-initialize

2.2.1 类与父类含+load

  • 先调用父类的+load方法
  • 再调用子类的+load方法
输出日志:
14:21:44.542004+0800 Category[4483:5050573] +[BFPerson load] 14:21:44.542545+0800 Category[4483:5050573] +[BFBoy load]
 

2.2.2 分类有load方法

  • 先调用类的+load方法
  • 再调用分类的+load方法
    • 分类的+load方法调用顺序与编译顺序一致
输出日志:
14:24:09.679907+0800 Category[4565:5054709] +[BFPerson load]
14:24:09.680555+0800 Category[4565:5054709] +[BFBoy load]
14:24:09.680632+0800 Category[4565:5054709] +[BFPerson load]--Work Cat
14:24:09.680749+0800 Category[4565:5054709] +[BFBoy load]--Tall Cat
14:24:09.680845+0800 Category[4565:5054709] +[BFBoy load]--Handsome Cat

2.3 核心流程

2.3.1 抽取+load方法

  • (1)抽取类的+load方法
    • a.先抽取父类的+load方法
    • b.再抽取子类的+load方法
  • (2)抽取分类的+load方法

2.3.2 调用+load方法

调用load方法,即将上一步抽取出来的方法列表loadable_classesloadable_categories,逐一调用即可。
  • (1)先调用类(包含父类)的+load方法
    • a.先调用父类+load方法
    • b.再调用子类+load方法
  • (2)调用分类的+load方法

2.4. 源码截取

2.4.1 抽取类+load 方法

2.4.2 分类方法抽取

2.4.3 +load方法调用

三、+initialize

3.1 源码导读

由于+initialize是在类第一次接收到消息是调用,我们调用[BFPerson alloc];时,就会调用。
我们根据汇编debug得到了下面流程:
然后,我们去objc4源码挖矿。
我们发现,12在源码中都是汇编,3是可读的C代码。就从3开始。
notion image

3.2 测试用例

测试用例源码在02-load-initialize

3.2.1 子类重写+initialize

  • 优先调用父类initialize
调用
此时打印如下:
13:44:35.437131+0800 Category[3527:4997267]   +[BFPerson initialize]
13:44:35.437240+0800 Category[3527:4997267]   +[BFBoy initialize]

3.2.2 分类重写+initialize

  • 会调用分类+initialize,不调用类本身的+initialize
调用:
打印输出
13:45:35.437121+0800 Category[3527:4997267]  +[BFPerson initialize]--Wrok Cat
 

3.2.3 多次调用initialize

多个子类均未实现,但父类实现+initialize方法,会多次调用+initialize
调用:
打印输出
13:52:44.968194+0800 Category[3786:5010745] +[BFPerson initialize] 13:52:44.968327+0800 Category[3786:5010745] +[BFPerson initialize] 13:52:44.968427+0800 Category[3786:5010745] +[BFPerson initialize]

3.3. 核心流程

类的初始化加载,会先调用父类+initialize方法,再调用类本身的+initialize

3.4. 源码截取

3.4.1 寻找方法

3.4.2 类的+initialize调用

参考

链接
  1. objc源码
 
示例代码
  1. 02-load-initialize