Ausgabe
Wenn wir in der Methode init nil zurückgeben, was passiert dann mit dem Retain-Count und wer wird dieses Objekt freigeben?
Wie ich verstehe, sobald wir alloc aufgerufen haben (was vor init passieren wird), wird der Retain-Zähler zu 1. Jetzt wird init aufgerufen und sagen wir, aus irgendeinem Grund kann es das Objekt nicht initialisieren, also gibt es null zurück.
Und es sieht so aus, als hätten wir jetzt das Objekt mit Retain Count gleich 1 und niemand hat einen Verweis darauf, um Release aufzurufen.
Sollten wir in diesem Fall [self autorelease] in init aufrufen oder etwas anderes tun?
Lösung
Siehe Objekte zuweisen und initialisieren in der Dokumentation.
Insbesondere wenn Sie einen Fehler in Ihrem Initialisierer haben, geben Sie Folgendes release
self
zurück nil
:
- init
{
self = [super init];
if (self) {
if (... failed to initialize something in self ...) {
[self release];
return nil;
}
}
return self;
}
Überlegen Sie nun, was passiert, wenn Sie anrufen [super init]
und es zurückgibt nil
. Das obige Muster wurde bereits verwendet, was self
freigegeben wurde, und die nil
Rückgabe zeigt an, dass die Instanz weg ist. Es gibt kein Leck und alle sind glücklich.
Dies ist auch ein gültiges Muster (nehmen Sie an, dass self
es sich um eine Instanz von handelt MyClass
):
- init
{
self = [super init];
if (self) {
... normal initialization here ...
} else {
self = [MyClass genericInstanceWhenInitializationGoesBad];
self = [self retain];
}
return self;
}
Da init
erwartet wird, dass etwas zurückgegeben wird, das ist retained
(durch die Verkettung von +alloc
), dann ist das [self retain]
, obwohl es doof aussieht, tatsächlich korrekt. Das self = [self retain]
ist nur extra defensiv für den Fall , MyClass
dass Überschreibungen retain
etwas Seltsames tun.
Beantwortet von – bbum
Antwort geprüft von – Gilberto Lyons (FixError Admin)