Pregunta

Estoy sufriendo de un mal pérdida de memoria de análisis de una de mis documentos XML.

Estoy usando el NSXMLParser para recorrer cada nodo (álbum en el XML de ejemplo a continuación), y luego repetir cada nodo foto y sumar el resultado a un NSArray.

Tengo 2 propiedades, que almacenan dos valores en cada bucle retenido. Estos valores se añaden a un objeto NSMutableDictionary junto con otro NSArray que contiene cada nodo foto. Se añade el diccionario resultante a un NSArray para ser utilizado en otra parte de la aplicación.

Tengo un botón que vuelve a cargar el documento XML en ciertos momentos de la aplicación. La próxima vez que se llama es cuando se producen las fugas. Instrumentos está mostrando NSCFArray y NSCFString son fugas y se está mostrando en didEndElement.

¿Dónde diablos estoy haciendo mal. Cualquier consejo sería de gran ayuda.

- (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];
}
}

Esto es un recorte del 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>
¿Fue útil?

Solución

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

Yo diría que esta línea es un culpable. La copia no se autoreleased o liberado, simplemente reemplazado cada vez que el analizador encuentra un elemento album. Uso:

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

Dado que va a crear una copia de la matriz, todos los objetos de la matriz también obtienen su retener recuento aumenta, por lo que si la matriz se vuelve inalcanzable (sobrescribiéndolo en el diccionario), todas las cadenas que la matriz contenía lo hará no será lanzado correctamente, y tampoco lo hará la matriz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top