1. 調用順序
以main為分界,load方法在main函數之前執行,initialize在main函數之后執行
2.相同點和不同點
2.1 相同點
- load和initialize會被自動調用,不能手動調用它們。
- 子類實現了load和initialize的話,會隱式調用父類的load和initialize方法
- load和initialize方法內部使用了鎖,因此它們是線程安全的。
2.2 不同點
- 子類中沒有實現load方法的話,不會調用父類的load方法;而子類如果沒有實現initialize方法的話,也會自動調用父類的initialize方法。
- load方法是在類被裝在進來的時候就會調用,initialize在第一次給某個類發送消息時調用(比如實例化一個對象),并且只會調用一次,是懶加載模式,如果這個類一直沒有使用,就不回調用到initialize方法。
3. load
在執行load方法之前,會調用load_images方法,用來掃描鏡像中的+ load符號,將需要調用 load 方法的類添加到一個列表中loadable_classes,在這個列表中,會先把父類加入到待加載列表,這樣保證父類在父類在子類錢調用load方法,而分類中的load方法會在類的load的方法后面加入另外一個待加載列表loadable_categories,這樣保證了兩個規則:
- 父類先于子類調用
- 類先于分類調用
在掃描完load方法加入到待加載方法后,會調用call_load_methods,先從loadable_classes調用類的load方法,call_class_loads;調用完loadable_classes后會調用loadable_categories中分類的load方法,call_category_loads。
調用順序如下:
- 父類load先于類添加到loadable_classes列表,通過call_class_loads,調用列表中的load方法,這樣父類的load先于類的load執行
- 當loadable_classes為空的時候,查看loadable_classes是否為空,如果不為空則調用call_category_loads加載分類中的load方法,這樣分類的load在類之后執行
4. initialize
initialize 只會在對應類的方法第一次被調用時,才會調用,initialize 方法是在 alloc 方法之前調用的,alloc 的調用導致了前者的執行。
initialize的調用棧中,直接調用其方法的其實是_class_initialize 這個C語言函數,在這個方法中,主要是向為初始化的類發送+initialize消息,不過會強制父類先發送。
與 load 不同,initialize 方法調用時,所有的類都已經加載到了內存中。
5. 使用場景
5.1 load
load一般是用來交換方法Method Swizzle,由于它是線程安全的,而且一定會調用且只會調用一次,通常在使用UrlRouter的時候注冊類的時候也在load方法中注冊
5.2 initialize
initialize方法主要用來對一些不方便在編譯期初始化的對象進行賦值,或者說對一些靜態常量進行初始化操作