一、+load方法
+load方法會在runtime加載類、分類時調(diào)用每個類、分類的
+load,在程序運行過程中只調(diào)用一次-
調(diào)用順序
- 先調(diào)用類的
+load- 按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
- 調(diào)用子類的
+load方法之前會先調(diào)用父類的+load
- 再調(diào)用分類的
+load
- 按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
- 先調(diào)用類的
-
objc4源碼解讀過程:objc-os.mm
_objc_initload_images-
prepare_load_methodsschedule_class_loadadd_class_to_loadable_listadd_category_to_loadable_list
-
call_load_methodscall_class_loadscall_category_loads(*load_method)(cls,SEL_load)
+load方法是根據(jù)方法地址直接調(diào)用,并不是經(jīng)過objc_msgSend函數(shù)調(diào)用
二、+initialize方法
+initialize方法會在類第一次接收到消息時調(diào)用-
調(diào)用順序
- 先調(diào)用父類的
+initialize,再調(diào)用子類的+initialize - (先初始化父類,再初始化子類,每個類只會初始化一次)
- 先調(diào)用父類的
-
+initialize和+load的最大區(qū)別是,+initialize是通過objc_Send進行調(diào)用的,所以有以下特點- 如果子類沒有實現(xiàn)
+initialize,會調(diào)用父類的+initialize(所以父類的+initialize可能會被調(diào)用多次) - 如果分類實現(xiàn)了
+initialize,就覆蓋類本身的+initialize調(diào)用
- 如果子類沒有實現(xiàn)
-
objc4源碼解讀過程
-
objc-msg-arm64.sobjc_msgSend
-
objc-runtime-new.mmclass_getInstanceMethodlookUpImpOrNillookUpImpOrForward_class_initializecallInitializeobjc_msgSend(cls,SEL_initialize)
-
三、__weak問題解決
- 在使用clang轉換OC為C++代碼時,可能會遇到以下問題
cannot create __weak reference in file using manual reference
- 解決方案:支持ARC、指定運行時系統(tǒng)版本,比如
xcrun -sdk iphoneos clang -arch ram64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-12.0.0 main.m