2017-03-15 4 views
0

Overriding initialize() ist üblich für die Ausführung von Code, bevor eine Klasse ihre erste Nachricht gesendet wird (Einstellung von UserDefaults usw.). Die Dokumentation besagt, dass eine übergeordnete Klasse Implementierung Subklassen mehrmals aufgerufen werden kann initialize() nicht außer Kraft setzen, und gibt ein Beispiel für eine Art und Weise, eine Klasse zu schützen Ausführung von Code mehr als einmal, wenn initialize() mehrmals aufgerufen wird:Overriding Initialize auf einem AppDelegate - Schutz vor mehrmaligem Code-Code

Die Die Superklassenimplementierung kann mehrmals aufgerufen werden, wenn die Unterklassen initialize() - die Laufzeit wird die vererbte Implementierung aufrufen - nicht implementieren oder Unterklassen explizit [super initialize] aufrufen. Wenn Sie sich selbst davon, dass laufen mehrere Male schützen möchten, können Sie Ihre Implementierung entlang dieser Linien strukturieren:

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

Ich bin zwingende initialize() in meinem AppDelegate und versuchen, mit Code zu vermeiden, mehr als einmal ausgeführt werden. Die Klassenüberprüfung ergibt für mich keinen Sinn, da überprüft wird, ob self is AppDelegate.Type immer als wahr ausgewertet wird (und gibt mir eine Warnung in Xcode).

Wird die Klassenüberprüfung nicht angewendet, da wir nicht in einer Oberklasse sind (die Oberklasse von AppDelegate ist UIResponder)? Wird der Inhalt meiner überschriebenen initialize()-Methode nur einmal ausgeführt, ohne super aufzurufen oder eine Klassenüberprüfung durchzuführen?

+0

Ich denke, wenn Sie '===' anstelle von 'ist' verwenden, wird es für Unterklassen von' AppDelegate' nicht wahr zurückgegeben. – dan

+0

@dan Hmm, ich habe keine Referenzen verglichen. Das ist auch eine gute Option und schützt vor Unterklassen. Sie sollten das als Antwort posten. – JAL

+0

Oder 'wenn self == AppDelegate.self'. Aber solange Sie AppDelegate nicht von der Unterklasse ableiten, brauchen Sie diese Überprüfung nicht. –

Antwort

0

Der Grund für die Klassenüberprüfung ist, dass Sie normalerweise Code nur unter initialize (wie in der Dokumentation) ausführen möchten. Das Schreiben dieser Bedingung schützt Sie vor Unterklassen, die initialize nicht implementieren oder [super initialize] aufrufen. Hier ist ein Beispiel Klassenhierarchie:

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


class Dog: Animal {} 

Als ich instanziiert ein neues Dog, die Objective-C-Laufzeit wird die initialize Methode jede Klasse in Dog ‚s-Hierarchie (Super zuerst) senden, so wird Dog erhalten die Nachricht, aber so wird Animal. Da Doginitialize nicht implementiert, wird die Superklasse die Nachricht erhalten. Wenn Sie also die Überprüfung nicht hinzufügen, die sicherstellt, dass die Nachricht für diese Klasse vorgesehen ist, wird Ihr Code zweimal ausgeführt.

Diese doesn't really make sense in Swift und wahrscheinlich noch viel weniger in einem AppDelegate so, wenn Sie Code nur einmal in Swift laufen haben wollen, sollten Sie wahrscheinlich träge initialisiert Globals oder statische Eigenschaften verwenden, wie in the migration docs definiert.