这段代码工作正常,但它给我一个代码行中的内存泄漏,该行显示了紫色在仪器中显示的泄漏,提到100.0%的行是
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
我会告诉你我的代码这是appdelegate文件didFinishLaunchingWithOptions方法: -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = [[NSURL alloc] initWithString:@"http://www.xyz.com/news.php?page_id=1"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[url release];
//Initialize the delegate.
NewsParser *parser = [[NewsParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(@"No Errors");
else
NSLog(@"Error Error Error!!!");
[parser release];
[xmlParser release];
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
此代码来自NewsParser文件NSXMLParser方法: -
- (NewsParser *) initXMLParser {
[super init];
appDelegate = (TWAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:@"posts"]) {
appDelegate.newsArray = [[NSMutableArray alloc] init];
}
else
{
if([elementName isEqualToString:@"page"])
{
aNewsInfo = [[NewsInfo alloc] init];
aNewsInfo.page = [[attributeDict objectForKey:@"id"] integerValue];
}
if(![elementName compare:@"smallimage"])
{
currentElementValue = [NSMutableString string];
}
if(![elementName compare:@"largeimage"])
{
currentElementValue = [NSMutableString string];
}
}
NSLog(@"Processing Element :%@",elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[[NSMutableString alloc] initWithString:string] autorelease];
else
[currentElementValue appendString:string];
NSLog(@"Processing Value: %@", currentElementValue);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:@"posts"])
return;
if([elementName isEqualToString:@"page"]) {
[appDelegate.newsArray addObject:aNewsInfo];
NSLog(@"%d",[appDelegate.newsArray count]);
NSLog(@"%@",aNewsInfo.title);
NSLog(@"%@",aNewsInfo.fulltext);
[aNewsInfo release];
aNewsInfo = nil;
}
else {
if ([elementName isEqualToString:@"smallimage"])
{
NSURL *url = [NSURL URLWithString:currentElementValue];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
[aNewsInfo setSmallImageData:image];
}
if(![elementName compare:@"largeimage"])
{
NSURL *imageURL = [NSURL URLWithString:currentElementValue];
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:data];
[data release];
[aNewsInfo setLargeImageData:image];
}
[aNewsInfo setValue:currentElementValue forKey:elementName];
[currentElementValue release];
currentElementValue = nil;
}
}
任何一个PLZ告诉我如何克服这个漏洞我即将在应用程序商店提交我的应用程序,但这是唯一的漏洞,请提出你的建议。
...谢谢
答案 0 :(得分:5)
您可以运行静态分析仪,它通常会显示泄漏的原因。它的 菜单中的“分析”,“构建”命令旁边。
答案 1 :(得分:2)
您知道如果只使用@property
和@synthesize
,然后正确使用getter和setter,您可以在99%的时间内减少此问题。
这条线看起来像对我来说最可疑之一
appDelegate.newsArray = [[NSMutableArray alloc] init];
假设newsArray
被声明为retain
的属性,在这种情况下,您将分配一个NSMutableArray
,其保留+1,然后将其设置为一个setter(如果设置为retain)将再给出+1。
这条线对我来说看起来不太好
currentElementValue = [NSMutableString string];
您正在为ivar指定一个自动释放NSMutableString
而没有ivar保留它。这可能会导致以后更难以跟踪问题。
有人指出init方法没有正确编写 - 这不是问题,但仍应修复。它看起来应该更像这样
- (NewsParser *)initXMLParser
{
self = [super init];
if (self) {
appDelegate = (TWAppDelegate *)[[UIApplication sharedApplication] delegate];
}
return self;
}
答案 2 :(得分:1)
而不是做
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
执行以下操作
NSData *xmlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData];
initWithContentsOfURL没有正确释放url,因此内存泄漏。 幸运的是,initWithData没有这个问题,提供了解决此内存泄漏的巧妙方法。