Frage

Aktualisieren : Ich habe das Code, aber das Problem weiterhin besteht ...

Hallo allerseits,
dies ist mein erster Beitrag hier - ich diesen Ort eine große Ressource für die Lösung viele meiner Fragen gefunden. Normalerweise versuche ich mein Bestes, alles auf eigene Faust zu beheben, aber dieses Mal habe ich wirklich keine Ahnung, was schief geht, so hoffe ich, jemand kann mir helfen.
Ich baue eine iPhone App, die ein paar XML-Dateien mit TouchXML analysiert. Ich habe eine Klasse XMLParser, die sich um das Herunterladen und Analysieren der Ergebnisse erfolgt. Ich erhalte Speicherlecks, wenn ich eine XML-Datei mehr als einmal analysiere mit der gleichen Instanz von XMLParser. Hier ist eine der Parsing-Schnipsel (nur der relevante Teil):

for(int counter = 0; counter < [item childCount]; counter++) {  
        CXMLNode *child = [item childAtIndex:counter];
        if([[child name] isEqualToString:@"PRODUCT"]) 
        {
            NSMutableDictionary *product = [[NSMutableDictionary alloc] init];
            for(int j = 0; j < [child childCount]; j++) {
                CXMLNode *grandchild = [child childAtIndex:j];
                if([[grandchild stringValue] length] > 1) {
                    NSString *trimmedString = [[grandchild stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    [product setObject:trimmedString forKey:[grandchild name]];
                }
            }

            // Add product to current category array
            switch (categoryId) {
                case 0:
                    [self.mobil addObject: product];
                    break;
                case 1:
                    [self.allgemein addObject: product];
                    break;
                case 2:
                    [self.besitzeIch addObject: product];
                    break;
                case 3:
                    [self.willIch addObject: product];
                    break;
                default:
                    break;
            }
            [product release];
        }

    }  

Das erste Mal, analysiere ich die xml kein Leck in Instrumenten auftaucht, das nächste Mal, wenn ich dies tun, ich habe eine Menge von Leckagen bekam (NSCFString / NSCFDictionary).
Instruments weist mich auf dieser Teil innerhalb CXMLNode.m , wenn ich in einem durchgesickerten Objekt graben:

theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
   xmlFree(theXMLString);
}

return(theStringValue);  

Ich habe wirklich eine lange Zeit und mehrere Ansätze versucht, dieses Problem zu beheben, aber bisher ohne Erfolg, vielleicht bin ich etwas fehlt wesentlich?

Jede Hilfe sehr geschätzt wird, danke!

War es hilfreich?

Lösung

Das Problem ist wahrscheinlich in dieser Zeile:

[self.mobil addObject:[product copy]];

für eine Kopie von product Durch den Aufruf sind Sie eine neue NSMutableDictionary-Instanz mit einem Beibehaltungszähler von 1. Die mobil Instanz erstellen, wird jedoch erhöhen den die Kopienzahl beibehalten, wenn Sie ihm die addObject: Nachricht zu senden, so dass die Beibehaltungszähler von die Kopie ist jetzt 2. Im Allgemeinen ist es eine Aufgabe für den Umgang mit seinem eigenen Objektspeicher verantwortlich ist, so jedes Mal, wenn Nachricht setFoo: oder addObject:, können Sie einfach das Objekt direkt übergeben, auch wenn seine Autoreleased oder Sie planen, um sie zu lösen direkt nach der Anruf; es liegt in der Verantwortung des Empfängers das Objekt, das Sie vorbei zu behalten, wenn sie auf ihn zu halten brauchen.

Weil Sie nicht die Kopie zu jeder Variablen zugewiesen haben, haben Sie nicht einen Zeiger, den Sie die Kopie des Beibehaltungszähler können nun verringern, dass Sie nicht mehr daran interessiert, so dass selbst wenn mobil gibt die Produktkopie an Irgendwann wird die Kopie nie das Objekt Original [product release] für Schleife Meldungen am Ende der Zählung von 0. Ihrer product Aussage behalten erreichen, nicht die Kopie, die Sie erstellt hat.

Stattdessen versuchen die folgenden und sehen, ob Instrumente glücklicher ist:

[self.mobil addObject:product];

Andere Tipps

In einfachen Worten, jedes Mal wenn Sie copy verwenden zu können, müssen auch irgendwo release / autorelease verwenden.

Und in diesem Fall, die noch einfache Antwort ist nicht copy in erster Linie zu verwenden, da Sie nicht mit der Originalversion von product etwas tun, nachdem Sie es kopiert haben.

Ich reparierte das Problem selbst. Es war irgendwie dumm, aber vielleicht könnte jemand über die gleiche Sache kommen, so werde ich es hier posten.

1) Ich änderbare Array einrichten als Instanzvariablen wie folgt hatte:

@interface XMLParser : NSObject {

// ...  
NSMutableArray *mobil;  
// ...  
}   
@property(nonatomic, retain) NSMutableArray *mobil;  
@end  

Jedesmal, wenn ich neue Daten wiederherstellen wollte innerhalb ich getan habe:
    self.mobil = nil;
Was tat nicht, was ich tun wollte, so ist dies der bessere Ansatz:
    [Self.mobil removeAllObjects];

2) Die dealloc Methode muss sein wie dies die Lecks zu reparieren (weil mobil als eine Eigenschaft definiert ist):
    - (void) {dealloc
      [Mobil release];
      self.mobil = nil;
  }

Puh, das eine Menge Arbeit gewesen, um herauszufinden - hoffen, dass es spart einige Zeit jemand anderes :-)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top