借助於可除錯的 objc 原始碼 了解了load
方法的具體流程。
建立乙個類xxobject
,新建乙個load
方法,打斷點,呼叫棧顯示,引出了dyld
和imageloader
。
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_listclass 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...