
+load 方法是類級方法,對比alloc等對象級方法,在 rumtime 中是個特殊的存在:
特點1:+load 由 rumtime 自動調(diào)用
與initialize不同,無論實現(xiàn)的類本身是否被使用,+load 一定會被調(diào)用。
特點2:+load 在main之前調(diào)用
具體是在dylb加載完二進(jìn)制文件之后,類被加載到runtime中時。因此,+load 比init方法更早執(zhí)行,還是個比main還要早執(zhí)行的存在。
特點3:+load 能夠保證只執(zhí)行一次
對比initialize,如果子類調(diào)用了[super initialize];,其父類的initialize方法會被調(diào)用多次,這就需要用特殊方法來進(jìn)行唯一性保護(hù),+load 則沒有這些煩惱,即使調(diào)用[super load]。
即使調(diào)用[super load]不會影響load的唯一性,卻會導(dǎo)致initialize的執(zhí)行“混亂”,因此你不應(yīng)該調(diào)用[super load]。
有些文章建議可以手動調(diào)用+load 方法,這里依然是不建議,鑒于+load的特殊性,手動調(diào)用破壞了唯一性:
凡是系統(tǒng)自動調(diào)用的,都不要手動干預(yù)。
特點4:可以在類別中定義 +load
定義在類別中的 +load 不會覆蓋類自己的 load 方法,并且總是按固定順序調(diào)用(見特點5),因此,使用類別調(diào)用 load 是安全的。
特點5:調(diào)用順序是固定的
- 類的+load方法在其所有父類的+load之后調(diào)用。
- 在類自己的+load方法之后調(diào)用類別 +load方法。
根據(jù)我的實驗觀察順序如下:
父類 > 類 > 類的類別 > 父類的類別
黑魔法的選擇
眾多iOSer稱Method Swizzling為黑魔法,實際上就是利用runtime的動態(tài)特性在向一個對象發(fā)送消息時“劫胡”,替換自己想要的方法,需要滿足必須調(diào)用一次,且只能調(diào)用一次的要求,如果有多個Swizzing,調(diào)用順序也必須是確定的,這些要求load都能滿足。
當(dāng)然,了解了+load方法的以上特點,不應(yīng)該用+load做以下用途(包含但不限于):
- load 方法中使用其他類。
- 不要執(zhí)行長時間操作,會導(dǎo)致APP超時啟動退出。
- 初始化對象數(shù)據(jù),可以這么理解,load執(zhí)行時,所在類只是被“注冊”,并沒有分配內(nèi)存。