2011-05-10 33 views
1

我正在使用TBXML從我的方法接收內存泄漏來解析XML文件。使用TBXML時的內存泄漏textFromElement

它給了我NSCFString'泄漏對象'。當我查看堆棧跟蹤時,其最後一次調用是使用TBXML方法textForElement;用於獲取元素中的字符串。

如果我點擊跟蹤它帶給我從TBXML類文件這個方法:

+ (NSString*) textForElement:(TBXMLElement*)aXMLElement { 
    if (nil == aXMLElement->text) 
     return @""; 
    return [NSString stringWithCString:&aXMLElement->text[0] encoding:NSUTF8StringEncoding]; 

這裏是方法之一使用textForElement:

- (NSMutableArray *)parseNewsXML 
{ 

NSString *newsURL = @"http://www.millersville.edu/news/rss.php"; 

NSMutableArray *newsArray = [[NSMutableArray alloc] init]; 

EventArticleObject *currentArticle = [[EventArticleObject alloc] init]; 


tbxml = [TBXML tbxmlWithURL:[NSURL URLWithString:newsURL]]; 
rootXMLElement = tbxml.rootXMLElement; 

if(rootXMLElement) 
{ 
    node_channel = [TBXML childElementNamed:@"channel" parentElement:rootXMLElement]; 

    if(node_channel) 
    { 
     node_item = [TBXML childElementNamed:@"item" parentElement:node_channel]; 

     while(node_item) 
     { 
      node_traverse = [TBXML childElementNamed:@"title" parentElement:node_item]; 
      NSString *title = [TBXML textForElement:node_traverse]; 
      title = [title stringByReplacingOccurrencesOfString:@""" withString:@"\""]; 


      [currentArticle setTitle:title]; 
      node_traverse = [TBXML childElementNamed:@"link" parentElement:node_item]; 
      NSString *link = [TBXML textForElement:node_traverse]; 
      [currentArticle setLink:link]; 
      [currentArticle setDate:nil]; 

      [newsArray addObject:currentArticle]; 
      node_item = node_item -> nextSibling; 
     } 
    } 
} 
[currentArticle release]; 
return newsArray; 
} 

這是第二個方法也收到相同的泄漏:

- (void)parseMuAlertXML 
{ 

time_t unixTime = (time_t) [[NSDate date] timeIntervalSince1970]; 

NSURL *url = [NSURL URLWithString:@"http://www.millersville.edu/alert/alert.xml"]; 

tbxml = [TBXML tbxmlWithURL:url]; 
rootXMLElement = tbxml.rootXMLElement; 

if(rootXMLElement) 
{ 
    node_alert = [TBXML childElementNamed:@"alert" parentElement:rootXMLElement]; 

    if(node_alert) 
    { 
     node_traverse = [TBXML childElementNamed:@"startdate" parentElement:node_alert]; 
     NSInteger startString = [[TBXML textForElement:node_traverse] intValue]; 
     time_t startTime = startString; 

     node_traverse = [TBXML childElementNamed:@"enddate" parentElement:node_alert]; 
     NSInteger endString = [[TBXML textForElement:node_traverse] intValue]; 
     time_t endTime = endString; 

     node_traverse = [TBXML childElementNamed:@"type" parentElement:node_alert]; 
     alertType = [[TBXML textForElement:node_traverse] retain]; 

     node_message = [TBXML childElementNamed:@"message" parentElement:node_alert]; 

     if(node_message) 
     { 
      node_traverse = [TBXML childElementNamed:@"p" parentElement:node_message]; 
      alertMessage = [TBXML textForElement:node_traverse]; 
      alertMessage = [[alertMessage stringByReplacingOccurrencesOfString:@" " withString:@" "] retain]; 
     } 

     if((unixTime >= startTime) && (unixTime <= endTime)) 
     { 
      [alertButton setHidden:NO]; 
      [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; 
     } else { 
      [alertButton setHidden:YES]; 
      [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; 
     } 
    } 
} 
} 

有沒有人看到最近發生了什麼錯? 謝謝。

回答

0

您分配了newsArray並在函數中返回它。你稍後發佈它,在哪裏使用它?

該工具似乎並不理解這一點。它認爲你已經分配並且不會釋放它。

理想情況下,您應該自動釋放需要從函數返回的對象。

+0

我添加了另一種方法,我收到相同的泄漏,我什麼也沒有返回。起初另一種方法也沒有返回任何東西,但仍然漏水。 – RyanG 2011-05-10 17:56:18

+0

我指的是parseNewsXML函數。你正在返回你已經分配的新聞數組。不知道你何時何地發佈它。嘗試讓它autorelease並再次檢查泄漏。 TBXML類文件泄漏表明其API中存在泄漏。 – 2011-05-10 18:22:52

+0

我正在處理newsArray並且沒有泄漏;它必須是與圖書館的東西。這很奇怪,因爲我解析了一些其他文檔,在使用textForElement時不會給我帶來任何問題。 – RyanG 2011-05-10 19:42:55

0

你當前的文章二傳可能是它。

您應該使用@synthesizer使其更簡單一些,否則請確保複製字符串,釋放舊字符串,並讓當前文章處理內存。如果你這樣做:

@implementation CurrentArticle 

- (void) setLink:(NSString*)value; 
{ 
    link = value; //You will either get a pointer to a value that belongs in another class, like pointing to an array instead of copying it, and changing the value, you'll be like "Why did it change?" 

///////////// OR THIS: 
     if(link) { 
    [link release]; 
    } 
    link = [value copy]; 
    [value release]; 
} 

合成器處理這個,可能更優雅。

但是,是的,我沒有看到你的問題是在上面的代碼裏面,它似乎是整個方式autoreleased值。

是的,我知道這是舊的,但那是我會看,我敢肯定其他人會尋找提醒這些字符串指針。由於有太多的常量和快捷方式,我們會被寵壞,但@「String」是一個常數,如果沒有保留它,它就會被釋放。