load and initialize

NSObject是一切OC類的基類,因此咱們必須對NSObject全部的方法有一個清楚的認識。安全

+ (void)load;app

當類或者分類被加入到runtime時,load方法會被調用,也就是說在main循環開始前load方法就已經被調用。ide

(當類被加載到進程的address space時,runtime就會給每一個類發送load消息。For classes that are in a shared (dynamically-loaded) library, the runtime sends the load message just after the shared library is loaded into the process's address space.)測試

因爲咱們不能肯定類加載到runtime中的時間,因此咱們要避免在load方法中調用其餘oc類。spa

注意:線程

  • 類的load方法,是在父類的load方法以後調用的
  • 分類的load方法,是在類的load方法以後調用的
  • 測試發現,只要類被加載到complie source中,即便沒使用它,該類同樣會被加載到runtime中
  • 在load中建立的對象在main循環以前,它們並沒被假如到AutoreleasePool中,須要本身手動來處理

+ (void)initialize;code

當類,或者任何繼承資它的類,在發送第一個消息以前,runtime會發送initialize消息給該類對象

  • 父類先收到initialize消息,子類再收到
  • 若是子類沒有實現initialize方法,父類可能收到initialize消息(),可使用下面的方法來阻止收到屢次消息
1 + (void)initialize {
2   if (self == [ClassName self]) {
3     // ... do the initialization ...
4   }
5 }
View Code
  • 每一個類的initialize只會調用一次
  • initialize是線程安全的,因此儘可能在initialize方法中作較少的事

源代碼分析:blog

運行時在調用_class_lookupMethodAndLoadCache時,會先調用void _class_initialize(Class cls),查找oc的源代碼(http://opensource.apple.com/source/objc4/objc4-646/runtime/objc-initialize.mm),實際上會先遞歸調用父類的_class_initialize方法,調用成功後,在調用((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize),即調用本身的initialize方法。繼承

總結來講:若是A:B:C:NSObject,當對A第一次調用方法時,會先調用B的initialize方法,在調用A的initialize方法。

相關文章
相關標籤/搜索