&이 NSXMLParser를 사용하는 사용자 정의 클래스를 사용하여 XML 파일을 구문 분석하고 있습니다. 첫 번째 호출에서는 모든 것이 정상이지만 두 번째, 세 번째 이후 호출에서는 didEndElement, didEndElement 및 foundCharacters 함수 내부의 특정 줄에서 수십 개의 메모리 누수가 표시됩니다. 나는 이걸 챙겨서이 문제가있는 사람들을 찾았지만, 정말로 도움이 될만한 것을 찾지 못했습니다.NSXMLParser 및 메모리 누수
내 파서 클래스는 다음과 같습니다
Parser.h
@interface XMLParser : NSObject {
NSMutableArray *data;
NSMutableString *currentValue;
NSArray *xml;
NSMutableArray *videos;
NSMutableArray *photos;
NSXMLParser *parser;
NSURLConnection *feedConnection;
NSMutableData *downloadedData;
Content *content;
Video *video;
BOOL nowPhoto;
BOOL nowVideo;
BOOL finished;
BOOL webTV;
}
-(void)parseXML:(NSURL*)xmlURL;
-(int)getCount;
-(NSArray*)getData;
//- (void)handleError:(NSError *)error;
//@property(nonatomic, retain) NSMutableString *currentValue;
@property(nonatomic, retain) NSURLConnection *feedConnection;
@property(nonatomic, retain) NSMutableData *downloadedData;
@property(nonatomic, retain) NSArray *xml;
@property(nonatomic, retain) NSXMLParser *parser;
@property(nonatomic, retain) NSMutableArray *data;
@property(nonatomic, retain) NSMutableArray *photos;
@property(nonatomic, retain) NSMutableArray *videos;
@property(nonatomic, retain) Content *content;
@property(nonatomic, retain) Video *video;
@property(nonatomic) BOOL finished;
@property(nonatomic) BOOL nowPhoto;
@property(nonatomic) BOOL nowVideo;
@property(nonatomic) BOOL webTV;
@end
에게 Parser.m
어딘가에#import "Content.h"
#import "Video.h"
#import "Parser.h"
#import <CFNetwork/CFNetwork.h>
@implementation XMLParser
@synthesize xml, parser, finished, nowPhoto, nowVideo, webTV;
@synthesize feedConnection, downloadedData, data, content, photos, videos, video;
-(void)parseXML:(NSURL*)xmlURL {
/*
NSURLRequest *req = [NSURLRequest requestWithURL:xmlURL];
self.feedConnection = [[[NSURLConnection alloc] initWithRequest:req delegate:self] autorelease];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
*/
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSXMLParser *feedParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
//NSXMLParser *feedParser = [[NSXMLParser alloc] initWithData:theXML];
[self setParser:feedParser];
[feedParser release];
[[self parser] setDelegate:self];
[[self parser] setShouldResolveExternalEntities:YES];
[[self parser] parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"articles"]) {
self.finished = NO;
self.nowPhoto = NO;
self.nowVideo = NO;
self.webTV = NO;
if (!data) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setData:tmp];
[tmp release];
return ;
}
}
if ([elementName isEqualToString:@"WebTV"]) {
self.finished = NO;
self.nowPhoto = NO;
self.nowVideo = NO;
self.webTV = YES;
if (!data) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setData:tmp];
[tmp release];
return ;
}
}
if ([elementName isEqualToString:@"photos"]) {
if (!photos) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setPhotos:tmp];
[tmp release];
return;
}
}
if ([elementName isEqualToString:@"videos"]) {
if (!videos) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setVideos:tmp];
[tmp release];
return;
}
}
if ([elementName isEqualToString:@"photo"]) {
self.nowPhoto = YES;
self.nowVideo = NO;
}
if ([elementName isEqualToString:@"video"]) {
self.nowPhoto = NO;
self.nowVideo = YES;
}
if ([elementName isEqualToString:@"WebTVItem"]) {
if (!video) {
Video *tmp = [[Video alloc] init];
[self setVideo:tmp];
[tmp release];
}
NSString *videoId = [attributeDict objectForKey:@"id"];
[[self video] setVideoId:[videoId intValue]];
}
if ([elementName isEqualToString:@"article"]) {
if (!content) {
Content *tmp = [[Content alloc] init];
[self setContent:tmp];
[tmp release];
}
NSString *contentId = [attributeDict objectForKey:@"id"];
[[self content] setContentId:[contentId intValue]];
return;
}
if ([elementName isEqualToString:@"category"]) {
NSString *categoryId = [attributeDict objectForKey:@"id"];
NSString *parentId = [attributeDict objectForKey:@"parent"];
[[self content] setCategoryId:[categoryId intValue]];
[[self content] setParentId:[parentId intValue]];
categoryId = nil;
parentId = nil;
return;
}
if ([elementName isEqualToString:@"vCategory"]) {
NSString *categoryId = [attributeDict objectForKey:@"id"];
NSString *parentId = [attributeDict objectForKey:@"parent"];
[[self video] setCategoryId:[categoryId intValue]];
[[self video] setParentId:[parentId intValue]];
categoryId = nil;
parentId = nil;
return;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!currentValue) {
currentValue = [[NSMutableString alloc] initWithCapacity:1000];
}
if (currentValue != @"\n")
[currentValue appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSString *cleanValue = [currentValue stringByReplacingOccurrencesOfString:@"\n" withString:@""] ;
if ([elementName isEqualToString:@"articles"]) {
self.finished = YES;
//[content release];
}
if ([elementName isEqualToString:@"article"]) {
[[self data] addObject:[self content]];
[self setContent:nil];
[self setPhotos:nil];
[self setVideos:nil];
/*
[content release];
content = nil;
[videos release];
videos = nil;
[photos release];
photos = nil;
*/
}
if ([elementName isEqualToString:@"WebTVItem"]) {
[[self data] addObject:[self video]];
[self setVideo:nil];
//[video release];
//video = nil;
}
if ([elementName isEqualToString:@"title"]) {
//NSLog(@"Tit: %@",cleanValue);
[[self content] setTitle:cleanValue];
}
if ([elementName isEqualToString:@"vTitle"]) {
[[self video] setTitle:cleanValue];
}
if ([elementName isEqualToString:@"link"]) {
//NSURL *url = [[NSURL alloc] initWithString:cleanValue] ;
[[self content] setUrl:[NSURL URLWithString:cleanValue]];
[[self content] setLink: cleanValue];
//[url release];
//url = nil;
}
if ([elementName isEqualToString:@"vLink"]) {
[[self video] setLink:cleanValue];
[[self video] setUrl:[NSURL URLWithString:cleanValue]];
}
if ([elementName isEqualToString:@"teaser"]) {
NSString *tmp = [cleanValue stringByReplacingOccurrencesOfString:@"##BREAK##" withString:@"\n"];
[[self content] setTeaser:tmp];
tmp = nil;
}
if ([elementName isEqualToString:@"content"]) {
NSString *tmp = [cleanValue stringByReplacingOccurrencesOfString:@"##BREAK##" withString:@"\n"];
[[self content] setContent:tmp];
tmp = nil;
}
if ([elementName isEqualToString:@"category"]) {
[[self content] setCategory:cleanValue];
}
if ([elementName isEqualToString:@"vCategory"]) {
[[self video] setCategory:cleanValue];
}
if ([elementName isEqualToString:@"date"]) {
[[self content] setDate:cleanValue];
}
if ([elementName isEqualToString:@"vDate"]) {
[[self video] setDate:cleanValue];
}
if ([elementName isEqualToString:@"thumbnail"]) {
[[self content] setThumbnail:[NSURL URLWithString:cleanValue]];
[[self content] setThumbnailURL:cleanValue];
}
if ([elementName isEqualToString:@"vThumbnail"]) {
[[self video] setThumbnailURL:cleanValue];
[[self video] setThumbnail:[NSURL URLWithString:cleanValue]];
}
if ([elementName isEqualToString:@"vDirectLink"]){
[[self video] setDirectLink: cleanValue];
}
if ([elementName isEqualToString:@"preview"]){
[[self video] setPreview: cleanValue];
}
if ([elementName isEqualToString:@"thumbnail_position"]){
[[self content] setThumbnailPosition: cleanValue];
}
if ([elementName isEqualToString:@"url"]) {
if (self.nowPhoto == YES) {
[[self photos] addObject:cleanValue];
}
else if (self.nowVideo == YES) {
[[self videos] addObject:cleanValue];
}
}
if ([elementName isEqualToString:@"photos"]) {
[[self content] setPhotos:[self photos]];
//[photos release];
//photos = nil;
self.nowPhoto = NO;
}
if ([elementName isEqualToString:@"videos"]) {
[[self content] setVideos:[self videos]];
//[videos release];
//videos = nil;
self.nowVideo = NO;
}
//[cleanValue release];
//cleanValue = nil;
[currentValue release];
currentValue = nil;
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Error" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
-(NSArray*)getData {
return data;
}
-(int)getCount {
return [data count];
}
- (void)dealloc {
[parser release];
//[data release];
//[photos release];
//[videos release];
//[video release];
//[content release];
[currentValue release];
[super dealloc];
}
@end
을 내 코드에서,이 클래스의 인스턴스를 생성 :
XMLParser* feed = [[XMLParser alloc] init];
[self setRssParser:feed];
[feed release];
// Parse feed
NSString *url = [NSString stringWithFormat:@"MyXMLURL"];
[[self rssParser] parseXML:[NSURL URLWithString:url]];
이제 문제는 첫 번째 (누수가없는) 이후에는 악기가이 부분과 같이 너무 많은 부분에 누출을 표시한다는 것입니다 (모든 항목을 열거하기에는 너무 많지만 모든 호출이 동일하게 보이기 때문에 누출 선을 굵게 표시했습니다) :
didEndElement에서이 pealse를 해결하는 방법
if ([elementName isEqualToString:@"link"]) {
// THIS LINE IS LEAKING => INSTRUMENTS SAYS IT IS A NSCFString LEAK
[self content] setUrl:[NSURL URLWithString:cleanValue]];
[[self content] setLink: cleanValue];
}
어떤 생각? (NSXMLParser Leaking
나를 위해 일한 .......... – sambasivarao4u