2010-08-23 11 views
12

Bitte helfen Sie mir bei diesem Speicherleck. Im Leck-Tool zeigt es ein Leck: NSCFString (32 Bytes) in der Bibliothek Foundation Verantwortlicher Frame: NSPropertyListSerialization. Ich gebe den Fehler aber trotzdem ein Leck aus. Was vermisse ich? Danke vielmals!Speicherleck mit Plist Serialisierung

NSPropertyListFormat format; 
    NSString *anError = nil; 
    id plist; 
    plist = [NSPropertyListSerialization propertyListFromData:rawCourseArray mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&anError]; 
    if (!plist){ 
      [anError release]; 
    } 
    NSArray *entries = (NSArray *)plist; 
    for (NSDictionary *entry in entries) 
    { 
     // DO SOMETHING 
    } 
+2

dies Es gibt verschiedene Beiträge über gibt es ein Apfel Fehler zu sagen, sagen einige NSPropertyListSerialization Optionen zu verwenden: Format: Fehler und andere sagen, Schalter zu JSON Serialisierung , aber ich habe noch keine gute Antwort gefunden. –

+5

Ich sehe einen Fehler: Du solltest '[anError release]' nicht in deinem Code machen; Sie besitzen nicht den Hinweis auf "anError". 'propertyListFromData:' hat es automatisch freigegeben, bevor es zu Ihrem Code zurückkehrt. Dies ist jedoch ein * double-free * Bug, kein * leak *. Ich sehe kein Leck in dem Code, den Sie gepostet haben. – Quuxplusone

+0

Im Debugger po den Wert der Zeichenfolge, die leckt, um zu sehen, ob es Ihnen Hinweise gibt. –

Antwort

0

Die Aussage plist = [NSPropertyListSerialization propertyListFromData:rawCourseArray mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&anError]; schafft ein Autorelease-Objekt. Wenn Ihr Code jetzt in einem separaten Thread ausgeführt wird, dem kein Autorelease-Pool explizit von @autoreleasepool {...} zugewiesen wurde, kann dieses Objekt nie freigegeben werden und ist ein Leck.
Stellen Sie daher sicher, dass Sie einen Autorelease-Pool eingerichtet haben, wenn Ihr Code in einem separaten Thread ausgeführt wird.

1

Stellen Sie zuerst sicher, dass Sie keine veralteten oder veralteten Methodenaufrufe verwenden. Abhängig von Ihrer App-Konfiguration (dies müssen Sie selbst entscheiden) verwenden Sie möglicherweise veraltete Methodenaufrufe. von Apple docs:

propertyListFromData:mutabilityOption:format:errorDescription: 

This method is obsolete and will be deprecated soon. (Deprecated. Use propertyListWithData:options:format:error: instead.)

habe ich einen Speicherverlust nicht erkennen, nach dem empfohlenen API-Aufruf ... Testcode verwenden:

NSArray *somearray = @[@"One",@"Two",@"Three"]; 
NSData *rawCourseArray = [NSKeyedArchiver archivedDataWithRootObject:somearray]; 

NSPropertyListFormat format; 
NSError *anError = nil; 
id plist; 
plist = [NSPropertyListSerialization propertyListWithData:rawCourseArray options:NSPropertyListImmutable format:&format error:&anError]; 
if (!plist){ 
    [anError release]; 
} 
NSArray *entries = (NSArray *)plist; 
for (NSDictionary *entry in entries) 
{ 
    // DO SOMETHING 
    NSLog(@"%@",entry); 
} 
+0

+1 Für die veraltete Methode, die wirklich das Problem sein kann. Aber, bitte entfernen Sie die '[Fehlerfreigabe]' Zeile, vielen Dank;) – Tricertops

+0

'propertyListWithData: Optionen: Format: Fehler:' hat auch ein Leck. – Leandros

0

Versuchen Sie dies, indem wir Wörterbuch in Temp

NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath]; 
    NSString *errorDesc = nil; 
    NSPropertyListFormat format; 
    NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc]; 
    if (!temp) 
    { 
     NSLog(@"Error reading plist: %@, format: %d", errorDesc, format); 
    } 
erhalten
0

gibt es kein Leck. wickeln Sie alles in einem @autoreleasepool ein, um sicher zu sein, dass alles, was automatisch freigegeben wird, sofort als Test abläuft.

DANN wird der potentielle Absturz, verursacht durch die doppelte Freigabe von anError: , es ist automatisch freigegeben und Sie müssen es nicht wieder freigeben!

0

Versuchen Sie, Ihre plist auf diese Weise zu lesen:

NSDictionary *dTmp=[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"]]; 


self.myarray=[dTmp valueForKey:@"Objects"];