前言
我們將3個類A、B同诫、C分別表示為父類卦停、子類、子類的分類來了解load和initialize
注意:
1.下文中所說的類都是直接或者間接繼承NSObject
2.這里只分析的類中實現(xiàn)+load和+initialize方法的情況岛请,不包含主動調用
使用場景
+load方法通常用來進行Method Swizzle
+initialize方法一般用于初始化全局變量或靜態(tài)變量
調用時機
load方法會在mian函數(shù)之前調用,會循環(huán)調用所有類(包括分類)的 +load 方法
initialize的調用是在第一次主動使用當前類的時候
調用次數(shù)
- load和initialize在類中只要實現(xiàn)都會調用一次(非super,非主動調用)
執(zhí)行的順序
+load方法:A -> B -> C ,即 父類 -> 子類 -> 分類
+initialize方法: A -> C ,即 父類 -> 分類
方法實現(xiàn)方式
+load使用函數(shù)內存地址的方式 (*load_method)(cls, SEL_load);
+initialize使用發(fā)送消息 objc_msgSend 的方式
子類和父類
load方法不會考慮對NSObject的繼承警绩,所有類實現(xiàn)load方法就會實現(xiàn)崇败,沒有也不會沿用父類方法
子類不實現(xiàn)initialize方法,父類實現(xiàn)initialize方法肩祥,子類沿用父類的方法
比如 父類A 中分別實現(xiàn)+load后室、+initialize方法,子類B中不實現(xiàn)+load混狠、+initialize方法
執(zhí)行的順序 [A load] -> [A initialize] -> [A initialize]
類和類別
本類和類別的+load方法存在就實現(xiàn)岸霹,不存在就不實現(xiàn)
類別中的+initialize方法會覆蓋本類的方法,只執(zhí)行一個類別的+initialize方法
安全性
- load和initialize方法內部使用了鎖将饺,所以都是線程安全的
其他注意點
- 在方法中如果使用super,load執(zhí)行的順序和次數(shù)依舊保持不變贡避,但是initialize的執(zhí)行順序和次數(shù)會變動,會調用多次予弧,所以開發(fā)中盡量不要使用super
2.在A刮吧、B、C的其中兩個類的+load方法中去都實現(xiàn)方法的替換操作掖蛤,由于方法置換2次使置換失效杀捻,所以+load中替換等操作加上dispatch_once保持執(zhí)行一次
3.不要去主動去調用load或者initialize方法,會失去他們調用的“唯一性”
4.load方法不會直接觸發(fā)initialize的調用蚓庭,但是不要再+load出現(xiàn)self等類方法的調用致讥,會使initialize的方法提前出現(xiàn),原因是使該類的第一條消息提前發(fā)生