2009-08-08 11 views
1

So einige, wo ich ein Leck habe, das mit dem Löschen eines Objekts unter bestimmten Umständen verbunden ist.Freigabe nach dem Entfernen aus einem Array & Referenzzeiger

Prämisse: - Ich habe ein NSMutableArray von Tree-Objekten (ein Tree-Objekt weiß, wie man sich zeichnet). - Ich habe einen Referenzzeiger (Tree * ausgewählt), der grundsätzlich auf den Baum zeigt, den ich zuletzt berührt habe. - Beachten Sie, dass der * ausgewählte Zeiger eine schwache Referenz ist.

Ok, so weit so gut.

Problem: Das Leck tritt auf, wenn ich einen Baum lösche. Aus der Liste stelle ich sicher, dass der Baum, der gelöscht wird, alles intern freigibt, bevor er aus dem Array entfernt wird (wenn er aus dem Array entfernt wird, sollte er automatisch Release aufrufen).

Was ich versuchte: ich bemerkte, dass mein Baum * ausgewählte Zeigern wird über die Selbst Eigenschaft den berührten Baum zugeordnet wird:

self.selected = Baum;

... und dadurch weiß ich, dass es beibehalten wird. Also was ich versuchte zu tun, war Anruf:

[self.selected release];

Ich rief dies direkt nachdem der Baum aus dem Array entfernt wurde. ... aber an diesem Punkt stürzt es im Wesentlichen ab, dass es bereits veröffentlicht wurde.

Frage: Warum erhalte ich diese Fehlermeldung? Ich habe es aus dem Array entfernt, aber mein self.selected Zeiger hat immer noch eine Zählung behalten, also sollte ich es nicht freigeben?

Vielleicht sollte ich es nach dem Entfernen auf Null setzen? Oder vielleicht sollte ich es vor dem Entfernen Prozess zu Autorelease setzen?

+0

Lassen Sie mich meine Frage überarbeiten: Da der * ausgewählte Zeiger eine beibehaltene Anzahl des Objekts im Array hat, warum würde das Entfernen dieses Objekts aus dem Array dazu führen, dass es freigegeben wird? Die Tatsache, dass ich einen Verweis darauf hatte, sollte verhindern, dass sie freigegeben wird, richtig? –

+0

Also was ich getan habe, war die Zuweisung des * ausgewählten Zeigers, ohne das self-Schlüsselwort zu verwenden. Nachdem ich den Entfernungsvorgang ausgeführt habe, rufe ich release weder auf den Ref-Zeiger noch setze ich ihn auf Null. Bis jetzt kein Leck !! –

+0

Scheiße. Lecks, Lecks, Lecks, es ist wieder da. –

Antwort

0

Was [wahrscheinlich] geschieht, ist selected verweist auf ein freigegebenes Objekt, nicht auf nichts.

würde ich

self.selected = nil; 

versuche stattdessen explizit zu. Das sollte auch für die Retain-Zählung sorgen.

1

Versuchen Sie nicht, das Beibehalten/Freigeben Ihrer selected Instanzvariable zu verwalten. Wenn Sie selected wollen eine schwache Referenz, erklären sie mit dem assign Attribut:

@property(nonatomic, assign) Tree *selected; 

Auf diese Weise wird es nicht beibehalten werden, wenn Sie einen Wert zuweisen. Konzeptionell wird es "huckepack" auf die Referenz, die Ihre NSMutableArray hält.Also, wenn Sie etwas von Ihrem NSMutableArray entfernen, tun Sie es ein bisschen wie folgt aus:

if (self.selected == toBeRemoved) 
    self.selected = nil; 
[myArray removeObject:toBeRemoved]; 

Wenn Sie nicht explizit assign angegeben haben und Ihr Eigentum sein Inhalt wurde beibehalten, wurden Sie wahrscheinlich eine Ausnahme, weil die nächste Aufgabe bekommen zu self.selected nach dem Entfernen eines Elements verursacht eine andere -release Nachricht an den alten Wert gesendet werden, der bereits von Ihrer [self.selected release] Nachricht freigegeben wurde.

0

grundsätzlich habe ich meine schwachen Referenzen mit 'self' zugewiesen, also intern aufrufen behalten. Ich habe das "Selbst" entfernt und jetzt sind die Dinge gut und dandy. :) danke!

Verwandte Themen