2010-11-22 15 views
1

In dem folgenden Code ist PersonListArray ein NSMutableArray und ich bekomme die Liste der Personen aus der SQLite-DB und fügen sie zu meinem Array.Speicherverlust beim Hinzufügen von Objekten zu Nsarray

Person* tmpPerson = [[Person alloc] init]; 
tmpPerson.personName = @"Mike"; 
tmpPerson.personEmail = @"[email protected]"; 

[PersonListArray addObject:tmpPerson]; 
[tmpPerson release]; 

Auch wenn ich hier das Objekt Person bin Loslassen, es ist ein Speicherleck zu geben, die ich vermute, ist aufgrund der Anordnung einen Referenzzähler, um es zu halten. Ich verwende das Array an anderer Stelle im Programm und lasse es dann sicher los.

Wie empfiehlt es sich, neue Objekte für ein Array zu erstellen und dieses Problem nicht zu lösen?

Im dealloc Methode, wo ich das Array freigeben

-(void) dealloc{ 
    [PersonListArray release]; // this contains the numerous Person objects 
    [super dealloc]; 
} 

sollte ich sie manuell wie dieser Stelle veröffentlichen?

-(void) dealloc{ 

    for (int i = 0; i<PersonListArray.count;i++) 
    { 
    Person * tmpPerson = [PersonListArray objectAtIndex:i]; 
    [tmpPerson release]; 
    } 

    [PersonListArray release]; 
    [super dealloc]; 
} 
+0

Hier ist mehr Code, um ein besseres Bild zu bekommen ... @ Schnittstelle Person: NSObject { \t NSString * personName; \t NSString * personMobile; \t NSString * personEmail; \t } @Eigenschaft (nicht atomar, behalten) NSString * personName, * personEmail, * personMobile; – ArdenDev

Antwort

0

Ihr Code, wie ursprünglich implementiert, ist korrekt. Ein Array behält Onjects bei, die hinzugefügt werden, und gibt sie entweder wieder frei, wenn sie aus dem Array entfernt werden oder wenn das Array freigegeben wird. Sie müssen nicht selbst durch das Array gehen.

Welche Mittel verwenden Sie, um das Leck zu erkennen? Wenn es Instrumente sind, dann magst du es falsch verstehen, was es dir sagt. Wenn es ein Leck erkennt, kann es Ihnen anzeigen, wo der Speicher zuerst zugewiesen wurde. Es kann Ihnen nicht zeigen, welches Objekt für das Leck verantwortlich ist. Ich würde daher raten, dass die angegebene dealloc-Methode nie aufgerufen wird (weil das Objekt geleakt wird) oder dass jemand anderes das Array behält und es nicht freigibt. Versuchen Sie, ein NSLog in dealloc zu setzen, um sicherzustellen, dass es auftritt; Als einmaliger Test könnten Sie versuchen, PersonListArray nach der Freigabe zu protokollieren - wenn das nicht zu einer Speicherausnahme führt, dann hat es höchstwahrscheinlich jemand anderes gespeichert.

[ENTFERNT: mein ursprünglicher Text "Versuchen Sie, einen NSLog von [PersonListArray retenrCount] zu Ihrem Dealloc hinzuzufügen, um herauszufinden, was der Fall ist."; Siehe Kommentar von bbum unten]

Die häufigste Ursache für versehentliche zusätzliche behält ist @ Eigenschaft/@ sythesize Eigenschaften, die festgelegt sind, beibehalten, aber für eine Zuordnung eine Freigabe nicht zu Dealloc hinzugefügt.

+0

Ich benutze Instrumente und das gleiche Verhalten auf dem Gerät. Die Dealloc-Methode wird immer noch aufgerufen. Wenn ich das Objekt <--> String-Konvertierung Methode wie oben erwähnt, gehen die Lecks weg. Das ist wirklich seltsam – ArdenDev

+0

Ist es möglich, dass Sie PersonName, PersonMobile und PersonEmail in Person dealloc freigegeben haben? – Tommy

+1

** Verwenden Sie nicht retainCount für Debugging-Zwecke **. Die absolute Retain-Anzahl eines Objekts ist ein Implementierungsdetail und möglicherweise nicht das, was Sie erwarten, während Sie sich weiterhin korrekt verhalten. – bbum

3

Der Code, den Sie uns zeigen, ist korrekt und enthält keine Lecks. Der letzte Abschnitt ist jedoch falsch und würde Ihr Programm zum Absturz bringen, da Sie Person Objekte freigeben, die Sie nicht mehr besitzen.

+0

SO jetzt, wenn ich versuche, das Person-Objekt in eine String-Liste zu konvertieren und es dem Array hinzuzufügen, funktioniert es, und ich bekomme keine Lecks in den Instrumenten. Aber jetzt muss ich jedes Objekt zum Zeitpunkt des Zugriffs auf das Objekt aus dem Array in String und umgekehrt umwandeln. – ArdenDev

0

An anderer Stelle in Ihrer App rufen Sie wahrscheinlich [PersonListArray objectAtIndex:n] an und leiten sie an verschiedene andere Teile Ihrer App weiter. Einer der anderen Teile Ihrer App wird wahrscheinlich verloren gehen.

Wenn Sie Lecks verwenden, klicken Sie auf den jeweiligen "Art von Leck", dann klicken Sie auf die Speicheradresse, und es zeigt Ihnen die Allok/Frei/behalten/Freigabe/Autorelease Verlauf dieser Speicheradresse. Wenn Sie die Detailansicht aktivieren (Cmd-E denke ich), werden Sie auch Stack-Traces für all diese sehen. Suchen Sie nach etwas, das eine Zurückbehaltung, aber keine entsprechende Freigabe vornimmt. (Es ist ein bisschen schwierig, wenn die Dinge von mehreren Autoreleased-Arrays beibehalten werden ...)

Verwandte Themen