2012-04-13 8 views
12

In einem Buch, sah ich, dass, wenn eine Unterklasse eine Methode der übergeordneten Klasse überschrieben wird, wirWarum in Objective-C verwenden wir self = [super init] statt nur [super init]?

self = [super init]; 

Zuerst haben kann, soll dies in der init Methode der Unterklasse zu tun?

Zweitens frage ich mich, warum der Anruf

[super init]; 

nicht gerade ist? Ich meine, zum Zeitpunkt des Aufrufs init wird der Speicher bereits von alloc zugewiesen (ich denke, FoobarFoobar ist der Name der Unterklasse. So können wir nicht [super init] anrufen, um die Mitgliedsvariablen zu initialisieren? Warum müssen wir die bekommen Rückgabewert von init und weisen self? ich meine, bevor [super init] Aufruf self auf einen gültigen Speicherzuweisung chuck gerichtet sein sollte ... also warum wieder etwas zu sich selbst zuweisen?

(wenn die Zuordnung wird nicht nur [super init]self 's vorhandenen Wert?)

+3

http://cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html –

+1

@AndreasCarlbom brillante Tutorial-Dank ... – Krishnabhadra

+0

mögliche Duplikat von [Warum sollte ich anrufen self = \ [super init \]] (http://stackoverflow.com/questions/2956943/why-should-i-call-self-super-init) –

Antwort

10

Warum also den von [super init] zurückgegebenen Wert an self übergeben? Mit Blick auf eine typische initializer Methode:

- (id)initWithString:(NSString *)aString { 
    self = [super init]; 
    if (self) 
    { 
     instanceString = [aString retain]; 
    } 
    return self; } 

Warum weisen wir [super init] Selbst hier?

Das Lehrbuch Grund ist, weil [super init] erlaubt ist einer der drei Dinge zu tun:

  1. ihren eigenen Empfänger zurück (der Selbst Zeiger ändert sich nicht) mit geerbte Instanzwerte initialisiert .
  2. Rückgabe eines anderen Objekts mit geerbten Instanzwerten initialisiert.
  3. Return Null, zeigt Fehler an.

Im ersten Fall hat die Zuordnung keine Wirkung auf mich selbst und die instanceString wird in dem ursprünglichen Objekt (die Linie festgelegt auf instanceString = [aString behalten]; könnte die erste Zeile der Verfahren gewesen und das Ergebnis wäre das gleiche).

Im dritten Fall ist die Initialisierung fehlgeschlagen. self wird auf Null gesetzt, , es wird keine weitere Aktion ausgeführt, und nil wird zurückgegeben.

Die Begründung Selbst für die Zuordnung mit dem zweiten Fall zugeordnet ist: wenn das zurückgegebene Objekt verschieden ist, wollen wir das:

instanceString = [aString retain]; which gets converted to 

self->instanceString = [aString retain]; to act on the correct value, 

so müssen wir den Wert der Selbst ändern, um diesen neuen zu Punkt Objekt.

der Hoffnung, das hilft ...

From Cocoa with Love

+0

interessant ... also wenn 'self' auf etwas zeigt Speicher zugewiesen, und dann wird "self" auf "nil" gesetzt, dann ist es wie ... macht sich selbst zu einer Art Phantom? Wenn es zum Beispiel ein "Duck" -Objekt ist, so verweist "duck" auf gültigen Speicher mit Elementvariablen, aber jetzt, wenn "self" auf "nil" gesetzt ist, wird es gewissermaßen zu einem Phantom, wie rechts Jetzt hat es keine Member-Variablen mehr (zeigt nicht auf einen zugewiesenen Speicher), und alles, was übrig bleibt, sind die Methoden, die Fähigkeit, Code ohne irgendeine "Substanz" auszuführen? –

+0

KEIN Objekt sollte sich selbst freigeben ... Der normale Weg dazu ist der Aufruf von -dealloc .. –

2

Es ist möglich, die Oberklasse könnte entscheiden, dass das Objekt nicht richtig initialisiert werden kann und null als Fehler zurückgibt. Wenn Sie nil nicht zu self zuweisen, wird Ihre init-Methode unter der Annahme fortgesetzt, dass die Elternklasse das Objekt korrekt initialisiert hat.

Es ist auch möglich, dass die Elternklasse auch ein völlig anderes Objekt zurückgibt, wenn sie möchte.

2

Verstehen Sie, dass die Objekt bereits alloced und selbst verweist auf einen Speicher.

Jetzt [Super-Initialisierung] führt den Initialisierungsteil.

1) Wenn die Initialisierung erfolgreich Selbstpunkte auf gleiches Objekt vor der Initialisierung ist

2) Wenn die Initialisierung Ausfall init Funktion gibt nil und self = null ist. Jetzt können wir überprüfen, ob das Objekt initialisiert wird und wenn ja unsere Magie tun durch diesen Code

if(self = [super init]){ 
    // do our magic 
} 

Es ist wie wir ein Imageview verwenden, normalerweise wir

UIImageView imgView = [[UIImageView alloc] init]; 

imgView verwenden nur nicht gleich Null haben Wert, wenn sowohl alloc als auch init erfolgreich sind.

3

Ein klassisches Beispiel für die Rückgabe eines anderen Objekts von -init ist die Implementierung eines Klassenclusters - eine abstrakte Schnittstelle mit mehreren konkreten Implementierern, die verschiedene Speicher oder Algorithmen bereitstellen. +[NSString alloc] gibt eine Instanz von NSPlaceholderString zurück. Die Initialisierer der Platzhalterinstanz überprüfen ihre Parameter, geben die Platzhalterzeichenfolge zurück und geben eine initialisierte Instanz einer konkreten Unterklasse NSString zurück.

Verwandte Themen