2010-01-06 10 views
24

Nehmen wir an, ich baue eine neue Klasse für das iPhone in Objective-C. In einer meiner Init-Methoden möchte ich manuell Speicherplatz reservieren. So könnte ich so etwas wie dieses:Wie sollte ich einen Fehler in einer init: -Methode in Objective-C behandeln?

- (id)initWithSomeObject:(SomeObject *)someObject { 
    self = [super init]; 
    if (self != nil) { 
    myObject = someObject; 
    [myObject retain]; 
    if ((memory = calloc(1, sizeof(SomeStruct)) == NULL) { 
     // What should I do here to clean up 
     [self release]; 
     self = nil; 
    } 
    } 
    return self; 
} 

Nimmt man nun an, dass die calloc() scheitern könnte, und dass der Speicher ist katastrophal für mein Objekt zuweisen versagt, was soll ich in der if-Körper tun zu reinigen richtig? Gibt es ein Objective-C-Idiom oder -Muster, das ich verwenden sollte?

Edit: Ich habe den Code von Rob Napier geschrieben. Aber ich muss myObject immer noch freigeben, oder? Oder löst der hinzugefügte Code irgendwie dealloc() aus?

+2

Mach dir keine Sorgen darüber, ob es dealloc() auslöst. Es tut, aber das ist nicht der Punkt. Der Punkt ist, dass [self release] den früheren Aufruf von + alloc ausgleicht, sodass alle erforderlichen Releases ausgeführt wurden und das System nun die Freigabe zum richtigen Zeitpunkt übernimmt. In den meisten Fällen ist "die passende Zeit" wahrscheinlich, sobald [Self Release] aufgerufen wird, aber es könnte später sein, wenn noch Autoreleases ausstehen. Aber der obige Code ist korrekt und nichts anderes ist erforderlich. –

+0

Als eine Randnotiz: Es ist mein Verständnis, dass Calloc/Malloc nie NULL zurückgeben wird, wird das System nur Ihre App töten, wenn Sie aus oder wenig Speicher. Ich nehme an, dass Apple dachte, dass das einfacher wäre, wenn die App von nicht aktivierten NULL/NIL-Zeigern abstürzt. –

Antwort

26

Ja, Sie sollten sich selbst befreien und dann nil zurückgeben.

[self release]; 
self = nil; 

Siehe Issues with Initializers in den Konzepten in Objective-C Programming Guide.

3

Sie müssen alles, was Sie benötigen, bereinigen und dann die Selbstreferenz auf setzen. Apple Dev Portal hat einen Artikel:

Link

+0

meine Güte - zumindest einen Kommentar hinterlassen, wenn Sie downvote! – psychotik

+0

Vergessen Sie nicht, sich selbst zu veröffentlichen, oder Sie werden lecken. (Keine Ahnung, wer runtergefallen ist; du hast Recht). –

1

ich gerade versucht. -dealloc wird wegen [self release] aufgerufen, so myObject müsste nicht in initWithSomeObject freigegeben werden. Um sicher zu gehen, könnten Sie myObject = [someObject retain]; verschieben (ich bevorzuge diesen Stil für den Fall, dass -retain aus irgendeinem Grund fehlschlagen könnte) unter dem Anruf, der fehlschlagen könnte (wenn das möglich ist).