本系列博客是本人的源碼閱讀筆記,如果有 iOS 開發者在看 runtime 的,歡迎大家多多交流。爲了方便討論,本人新建了一個微信羣(iOS技術討論羣),想要加入的,請添加本人微信:zhujinhui207407,【加我前請備註:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,歡迎一起討論
本文完整版詳見筆者小專欄:https://xiaozhuanlan.com/runtime
前言
load 方法中的最後一個函數:
_dyld_objc_notify_register(&map_2_images, load_images, unmap_image);
告訴我們,第一步是 map_2_images,第二步就是 load_images。筆者前面的文章也已經分析過,將文件或者類從 mach-o 裏讀出來後,進行 remap 等操作後放入相應的 hashmap 中,其實是做了第一步:緩存,爲了方便後面調用。而第二步 load_images,則是調用 load 方法。本文將給大家慢慢揭開 load 方法的神祕面紗。
分析
load 方法的實現如下:
void load_images(const char *path __unused, const struct mach_header *mh) {
if (!hasLoadMethods((const headerType *)mh)) return;
prepare_load_methods((const headerType *)mh);
call_load_methods();
}
去掉一些無關邏輯(主要是鎖操作和註釋)可以看出其實該方法就是兩部操作:
- 調用 load 方法之前的一些準備工作
- 開始調用 load 方法
大家可能會有一些困惑
- load 方法之前的 prepare,究竟 prepare 的是什麼?爲什麼要準備?
- 調用的大概順序是什麼?比如類 A 和 類 A 的父類都實現了 load 方法,甚至還有其 category 都實現了,那順序是怎麼樣的?下面筆者帶大家抽絲剝繭看代碼。