-init
和+initialize
是完全不同的東西。第一個用於初始化實例;第二個用於初始化類別。
第一次給任何給定的類發送消息時,運行時確保在其上調用+initialize
及其超類。超類首先被初始化,因爲它們需要在任何子類自身初始化之前做好準備。
所以,第一個是時間YourSubclass
被傳遞消息,運行時會做這樣的事情:
[NSObject initialize];
[YourClass initialize];
[YourSubclass initialize];
(雖然這是不太可能,這將是第一次NSObject
被傳遞消息,所以可能它不」噸需要在這一點上被初始化。這只是一個例子。)
如果YourSubclass
沒有實現+initialize
,然後上面顯示的[YourSubclass initialize]
調用將實際調用+[YourClass initialize]
。這只是工作中的正常繼承機制。這將會第二次調用+[YourClass initialize]
。
由於在+initialize
方法中完成的工作通常是應該只做一次的事情,所以警衛if (self == [TheClassWhoseImplementationThisMethodIsPartOf class])
是必要的。此外,這項工作通常假設self
是指當前正在編寫的課程,所以這也是警衛的原因。
您引用的第二個答案指出了一個例外,即使用+setKeys:triggerChangeNotificationsForDependentKey:
方法註冊KVO相關鍵的舊式機制。該方法特定於它所調用的實際類,而不是任何子類。你應該避免它,並使用更現代的+keyPathsForValuesAffectingValueForKey:
或+keyPathsForValuesAffecting<Key>
方法。如果你必須用舊的方式,把那部分放在警衛之外。此外,這種類的子類必須調用super
,這通常不會完成。
更新:
一個+initialize
方法通常不應通過,因爲運行時已經初始化超打電話super
。當且僅當已知超類使用舊機制來註冊依賴鍵時,則任何子類都必須通過super來調用。
在-init
的情況下不存在同樣的擔心,因爲運行時在調用您的函數之前不會自動調用超類的init方法。事實上,如果你的init方法沒有調用super
,那麼沒有任何東西會初始化超類的實例的「部分」。
初始化和初始化沒有任何關係。 – rmaddy
@rmaddy在'-init'裏面你有'self = [super init];'調用父母的'+ initialize',還是我不正確? – makaed
你是不正確的。在調用任何其他類或實例方法之前,每個類都調用一次initialize。 – rmaddy