Утечка памяти в NSMutableDictionary, NSArray в NSXMLParser

Я страдаю от плохой утечки памяти при синтаксическом анализе одного из моих XML-документов.

Я использую 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>

person Lee M    schedule 07.12.2009    source источник


Ответы (1)


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

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

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

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

person dreamlax    schedule 07.12.2009
comment
Готово. Теперь, когда вы на это указали, это совершенно очевидно. Я просидел здесь 3 часа, исправляя утечки памяти, это довольно большое приложение, и мне нужна вторая пара глаз. Еще раз спасибо. - person Lee M; 08.12.2009