1

У меня плохая утечка памяти, анализирующая один из моих XML-документов.Утечка памяти в NSMutableDictionary, NSArray в NSXMLParser

Я использую NSXMLParser для итерации каждого узла (альбом в примере xml ниже), а затем итерации каждого узла фотографии и добавления результата в NSArray.

У меня есть 2 сохраненных свойства, которые сохраняют два значения для каждого цикла. Эти значения добавляются к объекту NSMutableDictionary вместе с другим NSArray, содержащим каждый узел фотографии. Полученный словарь добавляется в NSArray, который будет использоваться в другом месте приложения.

У меня есть кнопка, которая перезагружает XML-документ в определенных точках приложения. В следующий раз, когда он называется, происходит утечка. Инструменты показывают, что NSCFArray и NSCFString протекают, и они появляются в didEndElement.

Где я нахожусь неправильно. Любые советы будут полезны.

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

Вот отрезок 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> 

ответ

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

Я думаю, эта линия является виновником. Копия никогда не автореализовывается или не выпускается, просто заменяется каждый раз, когда парсер сталкивается с элементом album. Использование:

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

Поскольку вы создаете копию массива, все объекты в массиве также получить их сохранить счетчик увеличивается, поэтому, если массив становится недоступным (путем перезаписи его в словаре), все строки, которые содержат массив, не будут выпущены должным образом, и ни один из них не будет массивом.

+0

Это сделано. Теперь, когда вы указали это, это совершенно очевидно. Я сидел здесь в течение 3 часов, фиксируя утечки памяти во всем, что довольно большое приложение, и мне нужна вторая пара глаз. Еще раз спасибо. –

+0

@ downvoter: WTF? – dreamlax

Смежные вопросы