Objective-C: Befestigungsspeicherverwaltung in einem Verfahren

stimmen
5

Verstehe ich es fast geschafft einfache Referenzzählung / Speicherverwaltung in Objective-C, aber ich bin eine schwierige Zeit mit dem folgenden Code aufweisen. Ich Freigabe mutableDict (im folgenden Code kommentiert) und es verursacht schädliches Verhalten in meinem Code. Wenn ich den Speicherverlust lassen, es funktioniert wie erwartet, aber das ist eindeutig nicht die Antwort hier. ;-) Würden jemand von euch erfahren Leuten so freundlich, mich wie in der richtigen Richtung zu zeigen, wie ich jede dieser Methode neu schreiben kann, um besser meinen Speicherbedarf zu umgehen? Vor allem mit, wie ich NSMutableDictionary * mutableDict bin Verwaltung, wie die großen Schuldige hier. Ich mag das Problem verstehen, und nicht nur Kopieren / Einfügen-Code - so einige Kommentare / Feedback ideal ist. Vielen Dank an Alle.

- (NSArray *)createArrayWithDictionaries:(NSString *)xmlDocument 
                               withXPath:(NSString *)XPathStr {

    NSError *theError = nil;
    NSMutableArray *mutableArray = [[[NSMutableArray alloc] init] autorelease];
    //NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
    CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError] retain]; 
    NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];
    int i, j, cnt = [nodes count];
    for(i=0; i < cnt; i++) {
        CXMLElement *xmlElement = [nodes objectAtIndex:i];
        if(nil != xmlElement) {
            NSArray *attributes = [NSArray array];
            attributes = [xmlElement attributes];
            int attrCnt = [attributes count];
            NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
            for(j = 0; j < attrCnt; j++) {
                if([[[attributes objectAtIndex:j] name] isKindOfClass:[NSString class]]) 
                    [mutableDict setValue:[[attributes objectAtIndex:j] stringValue] forKey:[[attributes objectAtIndex:j] name]];
                else 
                    continue;
            }
            if(nil != mutableDict) {
                [mutableArray addObject:mutableDict];
            }
            [mutableDict release];  // This is causing bad things to happen.
        }
    }

    return (NSArray *)mutableArray;
}
Veröffentlicht am 26/02/2009 um 23:32
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
5

Hier ist ein äquivalentes Umschreiben des Codes:

- (NSArray *)attributeDictionaries:(NSString *)xmlDocument withXPath:(NSString *)XPathStr {
    NSError *theError = nil;
    NSMutableArray *dictionaries = [NSMutableArray array];
    CXMLDocument *theXMLDocument = [[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError]; 
    NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];

    for (CXMLElement *xmlElement in nodes) {
        NSArray *attributes = [xmlElement attributes];
        NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary];
        for (CXMLNode *attribute in attributes) {
            [attributeDictionary setObject:[attribute stringValue] forKey:[attribute name]];
        }

        [dictionaries addObject:attributeDictionary];
    }

    [theXMLDocument release];
    return attributeDictionaries;
}

Hinweis Ich habe nur als Referenz zählen auf theXMLDocument. Das ist , weil die Arrays und Wörterbücher sprengt den Rahmen dieses Verfahrens leben. Die arrayund dictionaryKlassenmethoden erstellen Autoreleased Instanzen NSArrayund NSMutableDictionaryObjekte. Wenn der Anrufer sie nicht ausdrücklich beibehalten, werden sie automatisch auf der Ereignisschleife der freigegeben werden nächste go-round der Anwendung.

  • Ich entfernte Code auch , die nie ausgeführt werden würde. Die CXMLNode nameMethode sagt , es gibt eine Zeichenfolge zurück, so dass Test wird immer wahr sein.
  • Wenn mutableDictist nil, haben Sie größere Probleme. Es ist besser , dass es eine Ausnahme , als leise scheitern wirft, also tat ich weg mit diesem Test auch.
  • Ich habe auch die relativ neue forAufzählung Syntax, die mit Ihren Zählervariablen beseitigt.
  • Ich benannte einige Variablen und die Methode ein wenig mehr Cocoa-ish zu sein. Cocoa unterscheidet sich von den meisten Sprachen, dass es im Allgemeinen falsch betrachtet ein Verb wie „create“ zu verwenden, wenn Sie speziell der Anrufer verantwortlich für die Freigabe jedes Objekt Sie machen möchten.
  • Sie haben nichts mit theError. Sie sollten entweder überprüfen und die Fehler melden, sonst passieren in , nilwenn Sie sich nicht gehen zu überprüfen. Es hat keinen Sinn bei der Herstellung der App eine Fehler Objekt bauen sind Sie nicht verwenden würde.

Ich hoffe, das hilft erhalten Sie in der richtigen Richtung.

Beantwortet am 27/02/2009 um 00:18
quelle vom benutzer

stimmen
1

Nun, die Freigabe mutableDict wirklich keine Probleme sollte verursachen, weil die Leitung darüber (das Hinzufügen mutableDict zu MutableArray) wird es automatisch beibehalten. Während ich bin nicht sicher, was genau falsch mit Ihrem Code wird (Sie hat nicht angegeben, was „schlechte Dinge“ bedeutet), gibt es ein paar allgemeine Dinge, die würde ich vorschlagen:

  1. Autorelease MutableArray nicht sofort. Lassen Sie es eine regelmäßige alloc / init-Anweisung sein und Autorelease es, wenn Sie es zurück ( „return [MutableArray Autorelease];“).

  2. theXMLDocument undicht ist, sicher sein, dass zur Freigabe vor der Rückkehr. Auch brauchen Sie nicht, es zu behalten, wie Sie sind. alloc / init macht den Job durch das Starten der Objektanzahl bei 1 halten, es Halte wieder nur gewährleistet, es leckt für immer. Lassen Sie sich von der rid behalten und lassen Sie sie vor der Rückkehr, und es wird nicht auslaufen.

  3. Nur ein Tipp: Stellen Sie sicher, dass Sie den Rückgabewert dieser Methode beibehalten, wenn es an anderer Stelle verwendet - das Ergebnis Autoreleased wurde als nicht um garantiert zu sein, wenn Sie es brauchen, wenn Sie ausdrücklich behalten / loslassen irgendwo.

Andernfalls dieser Code sollte funktionieren. Wenn es immer noch nicht, eine andere Sache , die ich versuchen würde , vielleicht tut [MutableArray addObject: [mutableDict kopieren]] , um sicherzustellen , dass mutableDict verursacht Ihnen keine Probleme , wenn es freigegeben wird.

Beantwortet am 26/02/2009 um 23:49
quelle vom benutzer

stimmen
0

In Memory Management Programming Guide unter dem Thema Objekte aus Methoden zurückkehrend (scrollen ein wenig nach unten), gibt es ein paar einfache Beispiele, wie Objekte mit der richtigen Speicherverwaltung von einer Methode zurückzukehren.

Beantwortet am 08/09/2010 um 22:48
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more