我正在使用自定義類來解析XML文件,該類定製了&使用NSXMLParser。在第一次調用時,一切正常,但在第二次,第三次和以後的調用中,Instruments在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:
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];
}
任何想法如何解決這一問題pealse? 難道這是同樣的問題提到的(如蘋果的bug)李Amtrong這裏:NSXMLParser Leaking
它爲我工作.......... – sambasivarao4u 2011-01-18 12:42:21