我一直在编写一个使用NSXMLParser的应用程序 - 它正在杀死我
最初我曾经让解析器从网上下载了feed,并且它泄漏了大量的内存,现在我在某处读到使用NSURLConnection下载数据然后将其传递给解析器更好。问题是,我仍然泄露了记忆问题
任何人都有关于如何使这件事没有泄漏的任何提示?
非常感谢!
一般的想法是这样的。 RSSParser类是从viewDidLoad中的CategoriesController调用的。泄漏接缝将在RSSParser中发生,特别是这些行:
[parser parse]或[parsedItems addObject:[parsedItem copy]];
当我离开CategoriesController时会出现泄漏。
//RSSParser.h #import #import "Subscriptions.h" @interface RSSParser : NSObject { NSMutableArray *parsedItems; NSMutableDictionary *parsedItem; NSXMLParser *parser; NSString *item; NSString *ititle; NSString *link; NSString *description; NSString *guid; NSString *pubDate; } @property (nonatomic, retain) NSMutableArray *parsedItems; @property (nonatomic, retain) NSXMLParser *parser; - (void)fetch:(NSMutableData *)dt; @end
//RSSParser.m #import "RSSParser.h" @implementation RSSParser @synthesize parser, parsedItems; - (void)fetch:(NSMutableData *)dt { parsedItems = [[NSMutableArray alloc] init]; parser = [[NSXMLParser alloc] initWithData:dt]; [parser setDelegate:self]; [parser setShouldProcessNamespaces:NO]; [parser setShouldReportNamespacePrefixes:NO]; [parser setShouldResolveExternalEntities:NO]; [parser parse]; [parser release]; } - (void)parserDidStartDocument:(NSXMLParser *)parser { } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Probleme me te dhenat." message:@"Ju lutem provoni te rilidheni me vone." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; [errorAlert release]; } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ item = [[elementName copy] autorelease]; if ([elementName isEqualToString:@"item"]) { parsedItem = [[[NSMutableDictionary alloc] init] autorelease]; ititle = [[[NSMutableString alloc] init] autorelease]; link = [[[NSMutableString alloc] init] autorelease]; description = [[[NSMutableString alloc] init] autorelease]; guid = [[[NSMutableString alloc] init] autorelease]; pubDate = [[[NSMutableString alloc] init] autorelease]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ if ([item isEqualToString:@"title"]) { ititle = [ititle stringByAppendingString:string]; } else if ([item isEqualToString:@"link"]) { link = [link stringByAppendingString:string]; } else if ([item isEqualToString:@"description"]) { description = [description stringByAppendingString:string]; } else if ([item isEqualToString:@"guid"]) { guid = [guid stringByAppendingString:string]; } else if ([item isEqualToString:@"pubDate"]) { pubDate = [pubDate stringByAppendingString:string]; } } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ if ([elementName isEqualToString:@"item"]) { if (![ititle isEqualToString:@""]) { [parsedItem setObject:ititle forKey:@"title"]; } if (![link isEqualToString:@""]) { [parsedItem setObject:link forKey:@"link"]; } if (![description isEqualToString:@""]) { [parsedItem setObject:description forKey:@"description"]; } if (![guid isEqualToString:@""]) { [parsedItem setObject:guid forKey:@"guid"]; } if (![pubDate isEqualToString:@""]) { [parsedItem setObject:pubDate forKey:@"pubDate"]; } [parsedItems addObject:[parsedItem copy]]; } } - (void)parserDidEndDocument:(NSXMLParser *)parser { } @end
***************************************** //CategoriesController.m - (void)viewDidLoad { NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.ikub.al/RssCategory.aspx?catId=%@", address]]]; connection = [NSURLConnection connectionWithRequest:request delegate:self]; if (connection) { downloadedData = [[NSMutableData data] retain]; } else { NSLog(@"Cannot get the data stream."); } if ([address length] > 0) { UIBarButtonItem *subscribeButton = [[UIBarButtonItem alloc] initWithTitle:@"Abonohu" style:UIBarButtonItemStyleBordered target:self action:@selector(newSubscription)]; self.navigationItem.rightBarButtonItem = subscribeButton; [subscribeButton release]; } [super viewDidLoad]; } - (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response { [downloadedData setLength:0]; } - (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data { [downloadedData appendData:data]; } - (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error { UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Probleme me lidhjen." message:@"Ju lutemi te kontrolloni lidhjen tuaj WiFi, GPRS/EDGE/3G." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; [errorAlert release]; } - (void)connectionDidFinishLoading:(NSURLConnection *)theConnection { parser = [[RSSParser alloc] init]; [parser fetch:downloadedData]; parsedItems = [parser.parsedItems copy]; [parser.parsedItems release]; [categoriesTable reloadData]; [parser release]; }