-init
und +initialize
sind ganz andere Dinge. Die erste ist für die Initialisierung Instanzen; Die zweite ist für die Initialisierung Klassen.
Wenn eine Klasse zum ersten Mal eine Nachricht erhält, stellt die Laufzeitumgebung sicher, dass +initialize
darauf und ihre Oberklassen aufgerufen wird. Die Oberklassen werden zuerst initialisiert, da sie bereit sein müssen, bevor sich irgendeine Unterklasse initialisieren kann.
So, die ersten, die Zeit YourSubclass
messaged ist, kann die Laufzeit wie etwas tun:
[NSObject initialize];
[YourClass initialize];
[YourSubclass initialize];
(Obwohl es sehr unwahrscheinlich ist, dass dies das erste Mal sein würde, dass NSObject
messaged ist, so wahrscheinlich es doesn‘ t müssen an diesem Punkt initialisiert werden. Es ist nur zur Veranschaulichung.)
Wenn YourSubclass
nicht +initialize
nicht implementiert, wird der [YourSubclass initialize]
Aufruf oben gezeigt wird +[YourClass initialize]
tatsächlich nennen. Das ist nur der normale Vererbungsmechanismus bei der Arbeit. Das wird das zweite Mal, dass +[YourClass initialize]
aufgerufen wurde.
Da die Arbeit in einer +initialize
-Methode in der Regel die Art von Sache ist, die nur einmal durchgeführt werden sollte, ist der Schutz if (self == [TheClassWhoseImplementationThisMethodIsPartOf class])
erforderlich. Außerdem geht diese Arbeit oft davon aus, dass sich self
auf die aktuelle geschriebene Klasse bezieht, also auch ein Grund für den Wächter.
Die zweite Antwort zitiert eine Ausnahme, die der alte Stil Mechanismus zum Registrieren KVO-abhängige Schlüssel mit der +setKeys:triggerChangeNotificationsForDependentKey:
Methode ist. Diese Methode ist spezifisch für die tatsächliche Klasse, für die sie aufgerufen wird, und nicht für Unterklassen. Sie sollten es vermeiden und die moderneren Methoden +keyPathsForValuesAffectingValueForKey:
oder +keyPathsForValuesAffecting<Key>
verwenden. Wenn Sie den alten Weg benutzen müssen, legen Sie diesen Teil außerhalb des Schutzes. Außerdem müssen Unterklassen einer solchen Klasse bis super
durchgehen, was normalerweise nicht erfolgt.
Update:
Ein +initialize
Verfahren soll in der Regel nicht durch super
nennen, weil die Laufzeit bereits die übergeordnete Klasse initialisiert wird. Wenn und nur wenn die Oberklasse bekannt ist, abhängige Schlüssel unter Verwendung des alten Mechanismus zu registrieren, dann müssen alle Unterklassen zu super aufrufen.
Die gleiche Sorge existiert nicht im Fall von -init
, weil die Laufzeit nicht automatisch die Superklassen-Init-Methode für Sie aufruft, bevor Sie Ihre aufruft. Wenn Ihre Init-Methode nicht zu super
aufruft, dann hat nichts den "Teil" der Instanz der Superklasse initialisiert.
init und initialisieren haben nichts miteinander zu tun. – rmaddy
@rmaddy Innerhalb von '-init' hast du' self = [super init]; 'was die Eltern' 'initialize' 'aufruft, oder bin ich nicht korrekt? – makaed
Sie sind nicht korrekt. initialize wird einmal pro Klasse aufgerufen, bevor eine andere Klassen- oder Instanzmethode aufgerufen wird. – rmaddy