一到腥、+load方法
+load
方法會(huì)在runtime
加載類深寥、分類時(shí)調(diào)用每個(gè)類潮酒、分類的
+load
义屏,在程序運(yùn)行過程中只調(diào)用一次-
調(diào)用順序
- 先調(diào)用類的
+load
- 按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
- 調(diào)用子類的
+load
方法之前會(huì)先調(diào)用父類的+load
- 再調(diào)用分類的
+load
- 按照編譯先后順序調(diào)用(先編譯女责,先調(diào)用)
- 先調(diào)用類的
-
objc4源碼解讀過程:objc-os.mm
_objc_init
load_images
-
prepare_load_methods
schedule_class_load
add_class_to_loadable_list
add_category_to_loadable_list
-
call_load_methods
call_class_loads
call_category_loads
(*load_method)(cls,SEL_load)
+load
方法是根據(jù)方法地址直接調(diào)用漆枚,并不是經(jīng)過objc_msgSend
函數(shù)調(diào)用
二、+initialize方法
+initialize
方法會(huì)在類第一次接收到消息時(shí)調(diào)用-
調(diào)用順序
- 先調(diào)用父類的
+initialize
抵知,再調(diào)用子類的+initialize
- (先初始化父類墙基,再初始化子類,每個(gè)類只會(huì)初始化一次)
- 先調(diào)用父類的
-
+initialize
和+load
的最大區(qū)別是刷喜,+initialize
是通過objc_Send
進(jìn)行調(diào)用的残制,所以有以下特點(diǎn)- 如果子類沒有實(shí)現(xiàn)
+initialize
,會(huì)調(diào)用父類的+initialize
(所以父類的+initialize
可能會(huì)被調(diào)用多次) - 如果分類實(shí)現(xiàn)了
+initialize
掖疮,就覆蓋類本身的+initialize
調(diào)用
- 如果子類沒有實(shí)現(xiàn)
-
objc4源碼解讀過程
-
objc-msg-arm64.s
objc_msgSend
-
objc-runtime-new.mm
class_getInstanceMethod
lookUpImpOrNil
lookUpImpOrForward
_class_initialize
callInitialize
objc_msgSend(cls,SEL_initialize)
-
三初茶、__weak問題解決
- 在使用clang轉(zhuǎn)換OC為C++代碼時(shí),可能會(huì)遇到以下問題
cannot create __weak reference in file using manual reference
- 解決方案:支持ARC浊闪、指定運(yùn)行時(shí)系統(tǒng)版本恼布,比如
xcrun -sdk iphoneos clang -arch ram64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-12.0.0 main.m