1

Je souffre d'une fuite de mémoire mauvaise analysant un de mes documents XML. J'utilise NSXMLParser pour itérer chaque nœud (album dans l'exemple xml ci-dessous), puis itérer chaque nœud photo et ajouter le résultat à un NSArray.Une fuite de mémoire dans NSMutableDictionary, NSArray dans NSXMLParser

J'ai 2 propriétés retenues, qui stockent deux valeurs sur chaque boucle. Ces valeurs sont ajoutées à un objet NSMutableDictionary avec un autre NSArray contenant chaque nœud photo. Le dictionnaire résultant est ajouté à un NSArray pour être utilisé ailleurs dans l'application.

J'ai un bouton qui recharge le document xml à certains points de l'application. La prochaine fois que ça s'appelle, c'est quand les fuites se produisent. Instruments montre que NSCFArray et NSCFString fuient et que ça apparaît dans didEndElement.

Où est-ce que je me trompe? Tout conseil serait utile.

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
if([elementName isEqualToString:@"photo"]){ 
    self.strPhotoPath = [attributeDict objectForKey:@"iphone"]; 
}else if ([elementName isEqualToString:@"album"]) { 

    dicItem = [[[NSMutableDictionary alloc] init] autorelease]; 

    self.strCurrentTitle = [attributeDict objectForKey:@"band_name"]; 
    self.strCurrentLocation = [attributeDict objectForKey:@"location"]; 

} 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
if([elementName isEqualToString:@"photo"]){ 
    [self.arrPhotos addObject:self.strPhotoPath]; 
}else if ([elementName isEqualToString:@"album"]) { 
    [dicItem setObject:self.strCurrentTitle forKey:@"album"]; 
    [dicItem setObject:self.strCurrentLocation forKey:@"location"]; 
    [dicItem setObject:[self.arrPhotos copy] forKey:@"photos"]; 

    [self.arrAlbums addObject:dicItem]; 

    [self.arrPhotos removeAllObjects]; 
} 
} 

Voici un petit extrait du fichier XML.

<albums type='array'> 
<album location='Album 1' date='2009-12-04 22:47:48 UTC' album_name='' band_name='Band 1'> 
<photo display_on_website='true' standard='/system/photos/3396/original/Photo1-DSC8894.jpg' thumb='/system/photos/3396/thumb/Photo1-DSC8894.jpg' date='2009-12-04 22:47:48' exif_data='NIKON D300, F:2.8, Shutter:1/80, Focal:15mm, ISO:1600' iphone='/system/photos/3396/iPhone/Photo2-DSC8894.jpg' available_for_print='false'/> 
<photo display_on_website='true' standard='/system/photos/3403/original/Photo2-DSC9146.jpg' thumb='/system/photos/3403/thumb/Photo3-DSC9146.jpg' date='2009-12-04 23:19:27' exif_data='NIKON D300, F:4.5, Shutter:1/160, Focal:70mm, ISO:1600' iphone='/system/photos/3403/iPhone/Photo3-DSC9146.jpg' available_for_print='false'/> 
</album> 
<album location='Album 2' date='2009-12-04 22:47:48 UTC' album_name='' band_name='Band 2'> 
<photo display_on_website='true' standard='/system/photos/3396/original/Photo3-DSC8894.jpg' thumb='/system/photos/3396/thumb/Photo3-DSC8894.jpg' date='2009-12-04 22:47:48' exif_data='NIKON D300, F:2.8, Shutter:1/80, Focal:15mm, ISO:1600' iphone='/system/photos/3396/iPhone/Photo3-DSC8894.jpg' available_for_print='false'/> 
<photo display_on_website='true' standard='/system/photos/3403/original/Photo4-DSC9146.jpg' thumb='/system/photos/3403/thumb/Photo4-DSC9146.jpg' date='2009-12-04 23:19:27' exif_data='NIKON D300, F:4.5, Shutter:1/160, Focal:70mm, ISO:1600' iphone='/system/photos/3403/iPhone/Photo4-DSC9146.jpg' available_for_print='false'/> 
<photo display_on_website='true' standard='/system/photos/3403/original/Photo5-DSC9146.jpg' thumb='/system/photos/3403/thumb/Photo5-DSC9146.jpg' date='2009-12-04 23:19:27' exif_data='NIKON D300, F:4.5, Shutter:1/160, Focal:70mm, ISO:1600' iphone='/system/photos/3403/iPhone/Photo5-DSC9146.jpg' available_for_print='false'/> 
</album> 
</albums> 

Répondre

1
[dicItem setObject:[self.arrPhotos copy] forKey:@"photos"]; 

Je suppose que cette ligne est un coupable. La copie n'est jamais libérée ou libérée, juste remplacée chaque fois que l'analyseur rencontre un élément. Utilisation:

[dicItem setObject:[[self.arrPhotos copy] autorelease] forKey:@"photos"]; 

Puisque vous créez une copie du tableau, tous les objets du tableau aussi obtenir leur conserver le nombre a augmenté, donc si le tableau devient inaccessible (en le remplaçant dans le dictionnaire), tous les les chaînes contenues dans le tableau ne seront pas libérées correctement, pas plus que le tableau.

+0

C'est fait. Maintenant que vous l'avez souligné, c'est complètement évident. J'ai été assis ici pendant 3 heures à réparer des fuites de mémoire, ce qui est une application assez importante, et j'ai besoin d'une seconde paire d'yeux. Merci encore. –

+0

@downvoter: WTF? – dreamlax