2017-03-15 135 views
0

覆蓋initialize()對於在類發送其第一條消息(設置UserDefaults等)之前執行代碼很普遍。該文件指出,一個父類的實現可以被多次調用子類不重寫initialize(),並給予上述做法的例子,以保護類器件執行代碼不止一次如果initialize()多次調用:覆蓋AppDelegate上的初始化 - 防止多次執行代碼

的如果子類不實現initialize() - 運行時將調用繼承的實現 - 或者如果子類顯式調用[super initialize],則超類實現可能會被多次調用。如果你想保護自己免受多次運行,你可以在構造實現沿着這些線路:

+ (void)initialize { 
    if (self == [ClassName self]) { 
    // ... do the initialization ... 
    } 
} 

我重寫我的AppDelegate initialize(),並試圖避免多次運行有代碼。類檢查對我來說沒有意義,因爲檢查self is AppDelegate.Type是否總是會評估爲真(並在Xcode中給我一個警告)。

由於我們不是超類(AppDelegate的超類是UIResponder),類檢查是否不適用?我的覆蓋initialize()方法的內容只會運行一次,而不呼叫super或執行班級檢查?

+0

我想如果你使用'==='而不是'is',它將不會爲AppDelegate的子類返回true。 – dan

+0

@丹恩,我沒有考慮過比較參考。這也是一個不錯的選擇,可以防止子類。您應該將其作爲答案發布。 – JAL

+0

或'if self == AppDelegate.self'。但只要你不子類AppDelegate,你不需要檢查。 –

回答

0

類檢查的原因是因爲您通常只想在initialize上運行代碼(根據文檔)。編寫該條件可以保護您免受不執行initialize或致電[super initialize]的子類。下面是一個例子的類層次:

class Animal: NSObject { 
    class func initialize() { 
     //Some code I only want to run once 
    } 
} 


class Dog: Animal {} 

當我實例化一個新Dog,Objective-C的運行時間將initialize方法Dog的層次(超第一)發送到每類,所以Dog將接收消息,但將如此Animal。由於Dog未實現initialize,因此其超類將收到該消息,因此如果您未添加確保該消息是針對該類的檢查,那麼您的代碼將最終執行兩次。

doesn't really make sense in Swift,甚至可能更少在AppDelegate中如此,所以如果你想有代碼只在斯威夫特運行一次,你應該使用延遲初始化的全局或靜態的屬性,如the migration docs定義。