2009-07-25 8 views
2

Ich benutze das iPhone SDK 3.0, aber ich denke, das ist ein allgemeines Missverständnis, wie Dinge arbeiten w/c & Speicherverwaltung.Zeiger Speicherverwaltung Missverständnis w/Ziel-c

I außer Kraft gesetzt habe die viewWillAppear Methode wie diese

@implementation MyViewController 
- (void)viewWillAppear:(BOOL)animated { 
    NSArray *items = [NSArray arrayWithOjbects:self.searchButton, self.trashCan, nil]; 
    [self.bottomBar setItems:items animated:YES]; 
} 
// other stuff... 
@end 

wenn ich versuche, oben vom View-Controller wechseln weg und schalten alles richtig funktioniert wieder.

ABER, meine Neigung ist es, den ursprünglichen Zeiger auf "Elemente" "freizugeben", weil ich denke, ein Verweis auf das NSArray wird jetzt von BottomBar gehalten. Aber wenn ich das tue (siehe Code unten) und versuche, vom UIViewController abzuweichen, erhalte ich einen Speicherverwaltungsfehler (- [CFArray count]: Nachricht, die an freigegebene Instanz 0xd5f530 gesendet wird).

- (void)viewWillAppear:(BOOL)animated { 
    NSArray *items = [NSArray arrayWithOjbects:self.searchButton, self.trashCan, nil]; 
    [self.bottomBar setItems:items animated:YES]; 
    [items release]; 
} 

Muss ich in diesem Fall nicht Release Angaben müssen? Oder mache ich etwas falsch? Offensichtlich gibt der empirische Beweis an, dass ich "Einzelteile" nicht freigeben sollte, aber es ist mir nicht klar, warum dies der Fall ist.

Danke für jede Info/"Zeiger"!

+0

danke an alle! und danke für den Link. – user141146

Antwort

3

Sie müssen es nicht freigeben, weil Sie es nie eingeleitet haben. [NSArray arrayWithObjects:...] gibt ein automatisch freigegebenes Objekt zurück. Sie sind nicht für die Freigabe verantwortlich, da die Autorelease-Nachricht an sie gesendet wurde, als sie von der Methode zurückgegeben wurde. Sie müssen nur freigeben, was Sie init! (Wenn Sie verwendet hatte [[NSArray alloc] initWithObjects:...] Sie würden gehabt haben.)

+1

Es ist wahr, dass Sie nicht dafür verantwortlich sind, es zu veröffentlichen, aber es gibt keine Garantie, dass es ein automatisch freigegebenes Objekt ist. Alles, was Sie wissen, ist, dass Sie es nicht besitzen. Lesen Sie die Regeln unter . –

0

Wenn Sie arrayWithObjects: rufen NSArray:

NSArray *items = [NSArray arrayWithObjects:self.searchButton, self.trashCan, nil]; 

Sie ein Autoreleased Array zurückgegeben werden. Das Array wird Ihnen automatisch zurückgegeben, da Sie nicht alloc, new oder eine Methode aufrufen, die copy enthält. Dies bedeutet, dass Sie dieses Objekt nicht im Speicher verwalten müssen. (Werfen Sie einen Blick auf die Memory Management Programming Guide for Cocoa für weitere Informationen)

jedoch dann erhalten bleibt, wenn Sie setItems auf self.bottomBar rufen, vorbei an der Array als Argument, stoßen seine behalten bis 1 zählen, aber dann lassen Sie es, Rückkehr sein Retain-Wert wird auf Null zurückgesetzt, wodurch die Zuordnung aufgehoben wird.

Da das Array von self.bottomBar beibehalten wird, bedeutet dies, dass es den Speicher des Arrays verwaltet. Wenn es nicht mehr benötigt wird, wird das Array freigegeben, was impliziert, dass die Klasse das Array nicht mehr benötigt, was die richtige Art ist, den Speicher zu verwalten.

+0

Es ist wahr, dass Sie nicht dafür verantwortlich sind, es zu veröffentlichen, aber es gibt keine Garantie, dass es ein automatisch freigegebenes Objekt ist. Alles, was Sie wissen, ist, dass Sie es nicht besitzen. Lesen Sie die Regeln unter

0

Hier ist die kurze Version:

+ [NSArray arraywithobjects:] gibt ein Objekt, das Sie nicht besitzen, also nein, sollten Sie es nicht loslassen.

Auf der anderen Seite, wenn Sie getan hatte:

NSArray *items = [[NSArray alloc] initWithObjects:self.searchButton, self.trashCan, nil]; 

schafft dies ein Objekt mit einer Zählung von 1 halten, so dass Sie würde es loslassen müssen, um es zu verhindern, dass undicht.

Überprüfen Sie die Memory Management Programming Guide for Cocoa für weitere Details.

+0

Es ist wahr, dass Sie nicht dafür verantwortlich sind, es zu veröffentlichen, aber es gibt keine Garantie, dass es ein Autoreleased ist Objekt. Alles, was Sie wissen, ist, dass Sie es nicht besitzen. Lesen Sie die Regeln unter

+0

Ich bin mir der Unterscheidung bewusst, danke. Ich versuchte, Objective-C auf eine Weise zu erklären, die Objective-C verstehen würde. Deshalb wollte ich, wenn er dieses Thema wirklich vertiefen wollte, mit der gleichen Dokumentation in Verbindung treten, auf die Sie mich verwiesen haben. –

+0

Ich stimme zu, dass Ihre war die beste der Antworten, die auf diese Weise fehlgeschlagen. Aber wenn Sie den Unterschied kennen, fügen Sie den Neulingen keine Verwirrung hinzu. Sobald Sie beginnen, über Autoreleased-Objekte zu sprechen, fangen sie an, über Retain-Counts nachzudenken, und alles ist von da an abwärts. Die Speicherverwaltungsregeln sind einfach und leicht zu verstehen und sagen nichts über Autorelease- oder Retainer-Zählungen aus und doch werden Neulinge oft verwirrt, weil der Rat, den sie erhalten, über diese Dinge spricht. –

0

Um Himmels willen Jungs, zeigen Sie einfach Menschen auf die Memory Management Rules. Umschreibe sie nicht. Sagen Sie nicht "gibt ein automatisch freigegebenes Objekt zurück" (was nicht unbedingt wahr ist und auch dann nicht irrelevant ist, wenn es wahr ist). Richte sie einfach auf die Regeln.

Die Regeln sind eine Summe von 9 Paragraphen! Es besteht keine Notwendigkeit, sie zu paraphrasieren, sie abzuwerten oder sie neu zu formulieren. Sie sind klar und prägnant und explizit.

Lesen Sie die Regeln, folgen Sie den Regeln, und Sie haben keine Speicherverwaltungsprobleme.