首先調(diào)用時機不同,決定了完全不同的調(diào)用原理,形成了很大的差異。
寫在前面的話
最好不要在+load里初始化第三方的庫,很有可能app啟動耗時很久甚至失敗。
自己的業(yè)務邏輯多使用+initialize替代+load。
調(diào)用時機
+load 方法是在runtime加載類和分類的時候自動調(diào)用的,只會調(diào)用一次。不通過message_send()觸發(fā), 而是通過load_method這個結(jié)構(gòu)體里的IMP直接執(zhí)行,不符合OC的 消息分發(fā)機制。
+initialize方法會在類第一次接收到消息時被調(diào)用,如果子類沒有實現(xiàn)該方法,父類的+initialize方法,會被調(diào)用多次。通過message_send觸發(fā),符合OC的消息分發(fā)機制。
在繼承和分類里的調(diào)用順序。
- +load的調(diào)用順序
1.先調(diào)用類的+load
按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
調(diào)用子類的+load之前會先調(diào)用父類的+load
2.再調(diào)用分類的+load
按照編譯先后順序調(diào)用(先編譯,先調(diào)用)和繼承沒有關(guān)系
- +initialize的調(diào)用順序
1.在調(diào)用子類的+initialize方法時會先調(diào)用父類的+initialize方法,造成父類的+initialize方法會調(diào)用多次,但是并不會使父類初始化多次,每調(diào)用一次初始化的都是子類調(diào)用者的實例對象,所以每個類還是只被初始化一次(比如不同子類初始化之前,父類只會被初始化一次)。
2.分類會覆蓋原類+initialize方法的實現(xiàn)。
用途
- +load 常用于在main函數(shù)之前初始化一些重要的數(shù)據(jù),但會影響啟動時間。 經(jīng)常配合一次函數(shù)使用,防止手動多次調(diào)用+load方法。
+ (void) load
{
static dispatch_once_t token;
dispatch_once(&token, ^{
// init......
});
}
- initialize 用于懶加載一些類的初始化信息,或者注冊KVO監(jiān)聽,注冊通知,runtime方法交換。 經(jīng)常配合一次函數(shù)使用,子類多次調(diào)用時防止一些數(shù)據(jù)被多次創(chuàng)建,推薦使用。
+ (void)initialize
{
static dispatch_once_t token;
dispatch_once(&token, ^{
// init......
});
}
如有錯誤或者新的見解歡迎在評論區(qū)約談...