load和initialize常常被說起,但實際編碼中其實使用很少,一個知識即便當時瞭解的再清楚,一直不使用,也會慢慢忘記,就好像我如今想不起來高中物理的不少公式同樣。函數
提及這些總要提及原理,其實原理是什麼呢,就是蘋果在runtime的源碼中怎樣去調用這兩個方法的。細節不少,挑出關鍵流程其實也只能是知其然不知其因此然,只能是知道了這麼作,殊不知道爲何這麼作。優秀的源碼老是通過屢次測試屢次修改屢次優化的。測試
站在路的終點,咱們可能很難想起走在途中的心路歷程。仍是須要慢慢摸索,認真沉澱才行。優化
放個總結,方便回憶。ui
維度 | load | initialize |
---|---|---|
是否須要調用Super | 不須要 | 不須要 |
調用時機 | 類或者category加載到runtime時由系統自動調用 在main函數以前 | 在類或者子類在第一次收到消息時調用(類消息或者實例消息)在main函數以後 |
調用方式 | 直接經過函數的內存地址調用的,不走msg_send,不走OC消息轉發,每一個類的load方法都是獨立的 | 走OC消息轉發, msg_send |
調用次數 | 只會調用一次 | 1. 可能會調用屢次,若是子類沒有實現該方法,則子類在第一次收到消息時會調用父類的方法。2.若是在子類收到消息前,父類沒有收到過消息,那麼會先調用父類的initialize方法以後再調用子類的initialize方法。 |
調用順序 | 父類-子類-category 。1.全部的類都加載完以後纔會調用全部的category。 2.不一樣的類的load執行順序跟編譯順序有關,能夠在Target -> Build Phases -> Compile Sources 中調整順序。但全部的category都是在全部的類的load都執行完以後,纔會調的。 3.多個類的多個category或者一個類的不一樣category的load方法的順序一樣跟編譯順序有關,能夠在compiles source中調整。 | 父類-子類(若是category有實現,會只調用category中的實現;父類的category會覆蓋父類的實現,子類的category會覆蓋子類的category實現) |
使用 | 通常用來實現 Method Swizzle | 通常用來初始化全局變量 或者 靜態變量 |