2009-08-26 6 views
2

Ich bereite meinen Code in einer Telefonbuch-iPhone-Anwendung auf und das Leaks-Tool in Instruments meldet, dass ich NSCFString-Objekte lecke. Hier ist das Muster, das ich verfolge:Objective C NSCFString Leaks mit NSMutableArrays

ich eine Klasse Person in meiner Anwendung, die nichts anderes als lokales NSString Mitglieder und die damit verbundene Eigenschaften für Vornamen hat, Nachnamen usw.

My-View-Controller verfügt über eine NSMutableArray-Eigenschaft, die aus einer SQLite-Datenbank im searchBarSearchButtonClicked-Ereignis aufgefüllt wird. Dieses NSMutableArray wird mit Person-Objekten gefüllt, die zum Auffüllen meines TableView-Steuerelements verwendet werden. Wenn der Benutzer auf eine Person in der Ansicht klickt, wird ihr Person-Objekt außerdem an die Detailansicht übergeben, um zusätzliche Informationen anzuzeigen, die über den Namen hinausgehen.

Wenn ich meine erste Suche mache und die Ergebnisse anzeigen, gibt es keine Speicherlecks.

Jetzt, wenn ich meine zweite Suche mache, möchte ich idealerweise das NSMutableArray löschen und es mit der neuen Ergebnismenge neu laden, ohne Speicher zu verlieren. Also, um dies zu tun, rufe ich removeAllObjects auf meiner person Eigenschaft und dann die Datenbank rufen Sie die person NSMutableArray wieder zu bevölkern, wie unten dargestellt:

[self.personList removeAllObjects]; 
self.personList = [SearchService GetPersonList:searchText]; 
[list reloadData]; 

Durch den Aufruf removeAllObject ich die Lecks losgeworden habe, die ich verwendet haben Diese wurden mit den Person-Objekten verknüpft. Es scheint jedoch, dass ich jetzt die verbleibenden NSString-Objekte aus den Eigenschaften der einzelnen Person-Objekte lecke.

Ist das möglich?

Ich bin neu im Instrument-Tool, aber was ich aus dem Extended Detail ersehen kann, wenn ich in einen der NCSFString-Lecks bohre, ist, dass die letzte Codezeile im Stack oft auf die @ synthesize-Codezeile zeigt die Eigenschaft, wie zum Beispiel:

@synthesize firstName; 

Also, das ist, warum ich diese NSStrings denke nicht gereinigt zu werden. Gibt es einen besseren Weg, dies zu tun, der keine Speicherlecks erzeugt?

+0

Wenn Sie den Code für Ihre Person-Klasse veröffentlichen können, ist es möglicherweise einfacher zu diagnostizieren, was vor sich geht. – Mark

Antwort

3

Geben Sie die NSString s in der dealloc Methode für Ihre Personenklasse frei?

Unter der Annahme, dass Sie Ihre Immobilie als so einzurichten:

@property (retain) NSString *firstName; 

Wenn Sie firstName mit dem Setter gesetzt ist, wird es beibehalten werden. Wenn die Person Instanz dann freigegeben und freigegeben wird, aber firstName nicht freigegeben wurde, wird sie undicht.

Legen Sie es in der dealloc Methode in Ihrer Person Klasse:

- (void)dealloc 
{ 
    [firstName release]; 
    [super dealloc]; 
} 

(die entsprechende Ivar Unter der Annahme, die für Ihre firstName Eigenschaft verwendet wird, wird firstName genannt).

+0

Dies scheint zu funktionieren. Der Code-Analysator in XCode 3.2.1 kommentiert jedoch meine Freigabe in der Dealloc-Methode: "Falsche Dekrementierung der Referenzzählung eines Objekts gehört dem Aufrufer zu diesem Zeitpunkt nicht". Ideen? – rtemp

+0

Der Code-Analysator betrachtet die Verwendung von Accessor-Methoden in '-dealloc' als einen Fehler und warnt Sie davor - es gibt einige Diskussionen darüber, ob es zulässig ist, Accessoren in' init' und 'dealloc' zu verwenden, aber ich denke, der allgemeine Konsens ist zu steuern klar und greifen Sie direkt auf die Ivars zu (das hätte ich schon früher darauf hinweisen müssen). –

+0

Dies funktionierte für mich, obwohl meine Eigenschaft Setup war: @property (nonatomic, zuweisen) NSString * name; –