+load 和+initialize的區別

首先調用時機不同,決定了完全不同的調用原理,形成了很大的差異。

寫在前面的話

最好不要在+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......
    });
}

如有錯誤或者新的見解歡迎在評論區約談...

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容