1

XML 문서 중 하나를 구문 분석 할 때 메모리 누수가 심해서 고생하고 있습니다.NSMutableDictionary, NSArray NSXMLParser에서 메모리 누수가 발생했습니다.

NSXMLParser를 사용하여 각 노드 (아래 xml 샘플의 앨범)를 반복 한 다음 각 사진 노드를 반복하고 결과를 NSArray에 추가합니다.

나는 각 루프에 두 개의 값을 저장하는 2 개의 유지 된 속성이 있습니다. 이 값은 각 사진 노드를 포함하는 다른 NSArray와 함께 NSMutableDictionary 객체에 추가됩니다. 결과 사전은 NSArray에 추가되어 응용 프로그램의 다른 위치에서 사용됩니다.

나는 응용 프로그램의 특정 지점에서 XML 문서를 다시로드하는 버튼이 있습니다. 다음에 호출 될 때 누출이 발생합니다. Instrument는 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