type
status
date
slug
summary
tags
category
icon
password
本文是Objective-C系列的第5篇,主要讲述了及
load
和initialize
两个特殊方法的相关特性及其底层的实现。一、常用知识点
在讲述之前,我们先把该两个方法常用到的一些知识点先列出。
二、+load
2.1 源码导读
根据下列顺序,阅读objc源码即可。
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 Cat14:24:09.680749+0800 Category[4565:5054709] +[BFBoy load]--Tall Cat14: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_classes
、loadable_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源码挖矿。
我们发现,
1
、2
在源码中都是汇编,3
是可读的C代码。就从3
开始。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
调用
参考
链接
示例代码