1

我患有內存泄漏,解析我的一個xml文檔。NSMutableDictionary中的內存泄漏,NSXMLParser中的NSArray

我使用NSXMLParser迭代每個節點(下面的xml示例中的專輯),然後迭代每個照片節點並將結果添加到NSArray。

我有2個保留的屬性,它在每個循環中存儲兩個值。這些值與另一個包含每個照片節點的NSArray一起添加到NSMutableDictionary對象中。 生成的字典被添加到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個小時,修復了整個內存泄漏問題,這是一個相當大的應用程序,我需要第二雙眼睛。再次感謝。 – 2009-12-07 22:04:25

+0

@downvoter:WTF? – dreamlax 2012-06-13 10:02:13