iOS認識load方法

2022-08-30 06:54:12 字數 4011 閱讀 6777

意識到load方法是因為最近學習method swilzzing時發現與其它的系統方法不同。 當時建立了乙個uiviewcontroller的catagory並重寫了load方法。

這篇文章

中指出:

+ load 作為 objective-c 中的乙個方法,與其它方法有很大的不同。只是乙個在整個檔案被載入到執行時,在 main 函式呼叫之前被 objc 執行時呼叫的鉤子方法。其中關鍵字有這麼幾個:

針對提問進行整理學習

q1:load 方法是如何被呼叫的?

a1:當 objective-c 執行時初始化的時候,會通過 dyld_register_image_state_change_handler 在每次有新的映象加入執行時的時候,進行**。執行 load_images 將所有包含 load 方法的檔案加入列表 loadable_classes ,然後從這個列表中找到對應的 load 方法的實現,呼叫 load 方法。

q2:load 方法會有為我們所知的這種呼叫順序?

規則一:父類先於子類呼叫

規則二:類先於分類呼叫

a2:分析 schedule_class_load 和 call_load_methods 可得。

// 

在系統核心做好程式準備工作之後,交由 dyld(是the dynamic link editor 的縮寫,它是蘋果的動態鏈結器) 負責餘下的工作。

// 1、首先在整個執行時初始化時 _objc_init 註冊的**

dyld_register_image_state_change_handler(dyld_image_state_dependents_initialized, 0

/*not batch

*/, &load_images);

//2、每當有新的映象載入到 runtime 時,都會執行 load_images 方法進行**,並傳入最新映象的資訊列表 infolist

const

char * load_images(

enum

dyld_image_states state, uint32_t infocount,

const

struct

dyld_image_info infolist)

}if (!found) return

nil;

recursive_mutex_locker_t

lock

(loadmethodlock);

if(found)

return

nil;

}

//

4、呼叫 load_image_nolock

bool load_images_nolock(enum

dyld_image_states state,uint32_t infocount,

const

struct

dyld_image_info infolist

return

found;}//

5、呼叫 prepare_load_methods(將需要呼叫 load 方法的類新增到乙個列表中)

void prepare_load_methods(const headertype *mhdr)

/* 同理處理分類 */

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

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

}

//

6、呼叫 schedule_class_load (紅色**保證了父類在子類前面呼叫 load 方法)

static

void

schedule_class_load(class cls)

//

其中 add_class_to_loadable_list 新增到待載入的類的列表

void

add_class_to_loadable_list(class cls)

loadable_classes[loadable_classes_used].cls =cls;

loadable_classes[loadable_classes_used].method =method;

loadable_classes_used++;}//

其中 add_category_to_loadable_list 新增到待載入的分類的列表

void

add_category_to_loadable_list(category cat)

loadable_categories[loadable_categories_used].cat =cat;

loadable_categories[loadable_categories_used].method =method;

loadable_categories_used++;

}

//

7、呼叫 call_load_methods

void call_load_methods(void

) more_categories =call_category_loads(); --------------------------------》得出規則二

} while (loadable_classes_used > 0 ||more_categories);

...}

//  其中

call_class_loads 會從乙個待載入的類列表 loadable_classes 中尋找對應的類,然後找到 @selector(load) 的實現並執行。

static

void call_class_loads(void

)

if(classes) free(classes);

}

補充:1)什麼是映象?

2)由上得出

load_images -> load_images_nolock -> prepare_load_methods -> schedule_class_load ->

add_class_to_loadable_list

的呼叫過程。

objc 對於載入的管理主要使用了兩個列表,分別是 loadable_classes 和 loadable_categories。其中的

add_class_to_loadable_list就是將未載入的類新增到 loadable_classes 陣列中,add_category_to_loadable_list實現幾乎相同

3)相比於類 load 方法的呼叫,分類中 load 方法的呼叫就有些複雜了

static

bool call_category_loads(void

) }

//3. 將所有載入過的分類移除 `loadable_categories` 列表

shift = 0

;

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

else

}used -=shift;

//4. 為 `loadable_categories` 重新分配記憶體,並重新設定它的值

new_categories_added = (loadable_categories_used > 0

);

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

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

}if(loadable_categories) free(loadable_categories);

if(used)

else

return

new_categories_added;

}

iOS 比較load和initialize方法

ios中,類需要執行初始化操作才能正常使用。繼承於nsobject的類有兩種實現初始化類的方法 load initialize方法。void load 對於加入執行期的類或分類來說,如果該類實現了load方法,必定會呼叫此方法,且只呼叫一次。當包含類或分類的程式載入系統時,會執行該方法,一般都是程式...

iOS 的initialize和load方法

initialize和 load這兩個方法在類使用時會自動呼叫。但是兩個方法的不同點會導致應用層面上效能的顯著差異。1.initialize方法 這個方法會在第一次初始化這個類之前被呼叫,我們一般用來初始化靜態變數。initialize方法類似乙個懶載入,如果沒有使用這個類,那麼系統預設不會去呼叫這...

initialize方法與load方法比較

load方法和initialize方法類似點 1.都只會呼叫一次 2.父類在子類之前載入 複製 不同點在於 1.載入時間不同,load方法在main 函式前進行呼叫,initialize在第一次呼叫類的所屬方法時在呼叫 可能永遠不呼叫 2.load方法不會被category覆蓋。複製 initial...