2011-09-16 115 views
-1

可能重複:
Memory Leak In line of code內存泄漏代碼

該代碼工作正常,但它給了我一個內存泄漏的代碼行線是表示泄漏的一個通過提100.0%的紫色在儀表指示的行是

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; 

我會告訴你我的碼T他是的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告訴我如何克服這種泄漏我即將到在應用程序商店提交我的應用程序,但這是唯一的泄漏PLZ給你的建議。

謝謝...

+0

initXMLParser應該有'self = [super init];',但那不是你的泄漏。通常在調用init之後,你有'if(self){...} return self;' – Sam

+0

你可以包含你的dealloc嗎?如果你不在那裏發佈變量,你會得到泄漏。 – Sam

回答

4

可以運行靜態分析儀,它通常會告訴你該泄漏的原因。它是 「分析」菜單中的「生成」命令旁邊。

2

您知道如果您只是使用@property@synthesize,然後正確使用getter和setters,則可以減少約99%的時間出現此問題。

這行看起來像大多數犯罪嫌疑人之一,我

appDelegate.newsArray = [[NSMutableArray alloc] init]; 

即假設newsArray被聲明爲retain的屬性,在這種情況下,你會被分配一個NSMutableArray這將有保留+1,然後用一個setter(如果設置爲retain)進行設置,將會給出更多的+1。

這條線不看大我要麼

currentElementValue = [NSMutableString string]; 

你不伊娃採取保留它分配一個自動釋放NSMutableString到伊娃。這可能導致以後更難追蹤問題。

有人指出init方法沒有正確書寫 - 這不是問題,但應該仍然是固定的。它看起來應該更喜歡這種

- (NewsParser *)initXMLParser 
{ 
    self = [super init]; 
    if (self) { 
     appDelegate = (TWAppDelegate *)[[UIApplication sharedApplication] delegate]; 
    } 
    return self; 
} 
+0

是的,開發一種風格,你一貫地和宗教地使用屬性將大大減少內存錯誤。 –

1

而不是做

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; 

執行以下操作

NSData *xmlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData]; 

的initWithContentsOfURL不正確釋放的網址,因此內存泄漏。 幸運的是,initWithData沒有這個問題,提供了一個解決這個內存泄漏的簡單方法。

+0

這是如何解決任何問題的?除了你引入了兩個自動釋放的對象並選擇了一個稍微不同的初始化方法之外,它基本上是一樣的。 –

+0

NSXMLParser沒有發佈URL對象存在很長的問題。通過這種方式,您可以控制ARC – Frank

+0

正在發佈的網址。可能值得向您的答案添加任何引文,以便像我這樣的人不會質疑是否/爲什麼會起作用。此外,OP沒有使用ARC,因爲有釋放調用,所以這些只是簡單的舊自動釋放對象,當不再需要對象時不會釋放聰明。 –