Load 方法 暨 程式的載入順序

2021-09-11 21:04:06 字數 4189 閱讀 7279

借助於可除錯的 objc 原始碼 了解了load方法的具體流程。

建立乙個類xxobject,新建乙個load方法,打斷點,呼叫棧顯示,引出了dyldimageloader

dyld: the dynamic link editor

詳細可以看 sunnyxx

imageloader:

bootstrap initialization. registers our image notifier with dyld. called by libsystem before library initialization time

void _objc_init(void)

複製**

引導初始化

註冊通知,當二進位制檔案 images 載入到記憶體時,通知 runtime 進行處理。

unmap_image:處理將要 unmap 的 images

void

load_images(const char *path __unused, const struct mach_header *mh)

// call +load methods (without runtimelock - re-entrant)

// 呼叫 load 方法

call_load_methods();

}複製**

快速查詢,類和分類的方法列表中是否含有load方法,如果沒有,直接返回

遞迴查詢所有的load方法,並儲存起來

依次呼叫所有的load方法

1.2 prepare_load_methods

void prepare_load_methods(const headertype *mhdr)

// 獲取所有的分類

category_t **categorylist = _getobjc2nonlazycategorylist(mhdr, &count);

for (i = 0; i < count; i++)

}複製**

儲存當前類和父類的所有load方法,其中父類優先

儲存分類的load方法

1.2.1 schedule_class_load

schedule +load for classes in this image, any un-+load-ed superclasses in other images, and any categories in this image.

static void schedule_class_load(class cls)

複製**

1.2.2 add_class_to_loadable_list
class cls has just become connected. schedule it for +load if it implements a +load method

void add_class_to_loadable_list(class cls)

if (loadable_classes_used == loadable_classes_allocated)

loadable_classes[loadable_classes_used].cls = cls;

loadable_classes[loadable_classes_used].method = method;

loadable_classes_used++;

}複製**

根據 "load" 獲取對應方法的指標。其實方法實質上也是個物件,有它自己的成員變數,如下:

struct method_t 

複製**

靜態全域性陣列儲存,如果陣列已滿,動態擴容

add_category_to_loadable_list分類儲存方法,幾乎一致

call all pending class and category +load methods. class +load methods are called superclass-first. category +load methods are not called until after the parent class's +load

void call_load_methods(void)

// 2. call category +loads once

more_categories = call_category_loads();

// 3. run more +loads if there are classes or more untried categories

} while (loadable_classes_used > 0 || more_categories);

objc_autoreleasepoolpop(pool);

loading = no;

}複製**

首先,保證是首次執行,load方法只會執行一次。

建立自動釋放池,在池內執行方法,優化效能

do {} while迴圈執行,直到陣列為空,且分類方法也執行完畢,不再有新的分類方法

static bool call_category_loads(void)

(*load_method)(cls, sel_load);

cats[i].cat = nil;}}

// compact detached list (order-preserving)

// 3. 將載入過的分類方法移除 分離列表,保留未被載入過的 分類方法

shift = 0;

for (i = 0; i < used; i++) else

}used -= shift;

// copy any new +load candidates from the new list to the detached list.

// 執行過程中是否有新新增的分類方法

new_categories_added = (loadable_categories_used > 0);

// 4. 如果有,先儲存在 分離列表 cats

for (i = 0; i < loadable_categories_used; i++)

cats[used++] = loadable_categories[i];

}// destroy the new list.

// 釋放清空全域性列表,以便後面重新賦值

if (loadable_categories) free(loadable_categories);

// reattach the (now augmented) detached list.

// but if there's nothing left to load, destroy the list.

// 5. 是否存在有新列表,並賦值給全域性靜態儲存變數

if (used) else

if (printloading)

}return new_categories_added;

}複製**

+ (void)load

複製**

從方法呼叫棧中,找到了系統在執行load前呼叫的方法:

啟動 dyld,將二進位制檔案初始化

imageloader把二進位制檔案載入進記憶體

runtime 執行load_images,執行所有的load方法

執行自定義的load方法

load 的簡單了解

ios 程式 main 函式之前發生了什麼

你真的了解 load 方法麼?

load 方法全程跟蹤

Load 方法 暨 程式的載入順序

借助於可除錯的 objc 原始碼 了解了load方法的具體流程。建立乙個類xxobject,新建乙個load方法,打斷點,呼叫棧顯示,引出了dyld和imageloader。dyld the dynamic link editor 詳細可以看 sunnyxx imageloader bootstra...

Load 方法 暨 程式的載入順序

借助於可除錯的 objc 原始碼 了解了load方法的具體流程。建立乙個類xxobject,新建乙個load方法,打斷點,呼叫棧顯示,引出了dyld和imageloader。dyld the dynamic link editor 詳細可以看 sunnyxx imageloader bootstra...

load方法和 initialize方法的呼叫

一.load 方法 1.load 方法會在 runtime載入類 分類時呼叫 2.每個類 分類的 load 在程式執行過程中只呼叫一次 3.呼叫順序 3.1 先呼叫類的 load,按照編譯先後順序呼叫 先編譯,先呼叫 3.2呼叫子類的 load 之前會先呼叫父類的 load 3.3.再呼叫分類的 l...