2009-04-21 12 views
0

Ich habe dieses Problem schon seit längerem betrachtet und würde mich über jede Hilfe oder Vorschläge freuen. Ich bin sicher, es ist etwas Einfaches, aber ich kann es nicht finden. In meinem AppDelegate bin Laden ich eine Reihe von Zubehör Objekte up (ein Objekt, das ich geschaffen, die NSCopying unterstützt) mit dem folgenden Code:Probleme bei der Verwaltung von iPhone SDK-Mems - EXC_BAD_ACCESS

NSString  *path = [[NSBundle mainBundle] pathForResource:@"Accessories" ofType:@"plist"]; 
NSDictionary *accDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 

self.colors = (NSArray *) [accDict objectForKey:@"Colors"]; 
self.exteriorAccessories = [self loadAccessoriesForMode:EXTERIOR_MODE withDictionary:accDict]; 
self.interiorAccessories = [self loadAccessoriesForMode:INTERIOR_MODE withDictionary:accDict]; 
[accDict release]; 

Und das ist die Definition für das Verfahren seine Berufung:

-(NSArray *)loadAccessoriesForMode:(NSString *)mode withDictionary:(NSDictionary *) dictionary 
{ 
    NSMutableArray *tempValues = [[NSMutableArray alloc] init]; 
    for (NSDictionary *value in [dictionary objectForKey:mode]) 
    { 
     Accessory *accessory = [[Accessory alloc] initWithDictionary:value]; 
     [tempValues addObject:accessory]; 
     [accessory release]; 
    } 

    NSArray *returnArray = [[NSArray alloc] initWithArray:tempValues copyItems:YES]; 
    [tempValues release]; 
    [returnArray autorelease]; 

    return returnArray; 
} 

Wenn ich zur Freigabe für accDict komme, bekomme ich eine EXC_BAD_ACCESS Ausnahme. Wenn ich die Freigabe von Zubehör innerhalb der Schleife herausnehme, ist alles in Ordnung - aber ich lecke Zubehörobjekte (was mir obv. Erscheint - wenn ich es einleite und es zuweise, ist es meine Aufgabe, es freizugeben).

Wenn ich dies im Debugger durchlaufen, sehe ich die Init, kopieren und Dealloc-Methoden alle auf mein Accessory-Objekt wie erwartet auslösen. Ich kann auch Code für das Accessory-Objekt eingeben, wenn Sie denken, dass es hilft, aber ich denke, das Problem liegt irgendwo in diesem Code.

Antwort

3

Ich denke, ich habe die Ursache gefunden, aber ich werde es hier veröffentlichen, damit andere davon profitieren können. Es hatte wirklich nichts mit dem Code zu tun, den ich gepostet habe. Das Problem lag vielmehr im Accessory-Objekt. Ich habe Dinge direkt eingestellt, anstatt die Getter selbst zu nennen.

So folgt aus:

value = [dict objectForKey:@"myKey"]; 

Statt dessen:

self.value = [dict objectForKey:@"myKey"]; 

Irgendwie mich verursacht wurde auf der NSDictionary schlechte Nebenwirkungen haben sich (ich dachte, dass nicht wandelbar war, aber es scheint, Ich habe es irgendwie vermasselt). Der einzige Weg, den ich gefunden habe, war den sehr hilfreichen Ratschlag that I found on Cocoa With Love zu verwenden.

Als ich die Option Beschreibung drucken in XCode verwendete, konnte ich sehen, dass das NSDictionary irgendwie AccessoryValue-Objekte enthielt - eines meiner benutzerdefinierten Objekte, das NICHT da sein sollte, da dieses gerade von einem einfachen Plist geladen wurde. Drucken Beschreibung befindet sich in XCode, indem Sie den Mauszeiger über das Objekt bewegen, um dessen Details anzuzeigen (während der Prozess im Debugger angehalten wurde) und auf die kleinen Auf-/Ab-Pfeile rechts neben dem Dreieck klicken, das in Objektdetails expandiert. Bei Wörterbüchern wird der gesamte Inhalt auf die Konsole übertragen.

+0

Es ist wichtig zu wissen, wie die Eigenschaft „Wert“ definiert ist und was in seinen Accessormethoden passiert. Gibt es da noch Überreste und Freisetzungen? –

+0

Ja, Wert ist eine Eigenschaft mit (nicht atomisch, behalten). Meine Vermutung war also, dass das Aufrufen von "value =" nur den Zeiger auf den Aufruf von retain setzt, wohingegen "self.value =" die entsprechende Setter-Methode aufruft und somit die Retain-Funktion aufruft. – Bdebeez

0

Bitte Präfix dies mit einem „Ich weiß nichts über Objective-C, aber“:

Es sieht für mich wie Sie die Zubehörteile lösen müssen, nachdem Sie sie in die „returnarray“ kopiert haben, oder vielleicht auch nicht angeben "copyItems".

0

Führen Sie Clang auf Ihrem Code. Es ist ein Glücksfall. Clang Regeln! Es wird eine statische Analyse Ihres Codes durchführen und Ihnen sagen, was Sie möglicherweise verlieren. Tolles Zeug.

0

Ich kämpfte einen Tag lang mit dem Exc_Bad_Access Problem und fand schließlich die Antwort. Das Problem war, wenn ich versuche, auf eines der in einem NSDictionary gespeicherten Objekte zuzugreifen, das erste Mal war OK, aber der zweite Zugriff auf das Objekt wurde auf Null gesetzt, obwohl das Objekt im Wörterbuch gleich bleibt. Dieses seltsame Verhalten war darauf zurückzuführen, dass das Objekt zweimal freigegeben wurde.Hier ein Beispiel:

NSString * nstring = [[[[NSString Alloc] init] Autorelease] [AnNSDictonaryInstance setObject: nstring forKey: 0];

... [nstring release];

Beachten Sie, dass nstring wurde Autorelease gesetzt und dann wieder freigegeben? Es wird kein Problem sofort angezeigt. Sie versuchen das Wörterbuchobjekt das zweite Mal zu lesen. Ich hoffe, eines Tages wird das Entwicklungsteam von Apple in der Lage sein, dies als eine Verletzung beim Kompilieren zu kennzeichnen.

Ich hoffe, dass dieser Beitrag jemandem helfen wird.

Wayne Campbell

Verwandte Themen