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