0

我在我的應用程序中使用XMLparser。它運行良好,但是當我在樂器中運行我的應用程序時,我一直在處理XML出來的字符串的NSMutableString獲取內存泄漏。XML解析器中的內存泄漏與NSMutableString

問題是這個內存泄漏只發生在我第二次執行特定的調用(登錄)時。當我進行其他調用時,我沒有發現內存泄漏。

給出泄漏的NSMutableString是'textInProgress'。

- (NSDictionary *)objectWithData:(NSData *)data 
{ 


    [dictionaryStack release]; 
    [textInProgress release]; 

    dictionaryStack = [[NSMutableArray alloc] init]; 
    textInProgress = [[NSMutableString alloc] init]; 

    [dictionaryStack addObject:[NSMutableDictionary dictionary]]; 

    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; 
    parser.delegate = self; 
    BOOL success = [parser parse]; 
    [parser release]; 

    if (success) 
    { 

     NSDictionary *resultDict = [dictionaryStack objectAtIndex:0]; 
     return resultDict; 
    } 

    return nil; 
} 


- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    NSMutableDictionary *parentDict = [dictionaryStack lastObject]; 
    NSMutableDictionary *childDict = [NSMutableDictionary dictionary]; 

    [childDict setObject:attributeDict forKey: NODE_ATTR_KEY]; 

    id existingValue = [parentDict objectForKey:elementName]; 
    if (existingValue) 
    { 
     NSMutableArray *array = nil; 
     if ([existingValue isKindOfClass:[NSMutableArray class]]) 
     { 
      array = (NSMutableArray *) existingValue; 
     } 
     else 
     { 
      array = [NSMutableArray array]; 
      [array addObject:existingValue]; 

      [parentDict setObject:array forKey:elementName]; 
     } 

     [array addObject:childDict]; 
    } 
    else 
    { 

     [parentDict setObject:childDict forKey:elementName]; 
    } 

    [dictionaryStack addObject:childDict]; 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    NSMutableDictionary *dictInProgress = [dictionaryStack lastObject]; 

    if ([textInProgress length] > 0) 
    { 
     [dictInProgress setObject:textInProgress forKey:NODE_VALUE_KEY]; 

     [textInProgress release]; 

     textInProgress = [[NSMutableString alloc] init]; <--- Object leaks here 

    } 

    [dictionaryStack removeLastObject]; 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    [textInProgress appendString:string]; <--- Object leaks here 

} 

我已經調試整天,仍然無法找到解決方案,這個問題。泄漏只包含64個字節的數據。

這裏同時泄漏的兩張截圖工具內 - >泄漏 - >調用樹 leak at XML parser foundCharacters

leak at XML parser didEndElement

希望有人能幫助我!


編輯:

對於這些泄漏的解決方案是聲明的NSMutableString和的NSMutableDictionary作爲屬性。 (請參閱Neal他的評論)

回答

2

我會建議您將textInProgress轉換爲屬性而非ivar。就像這樣:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    NSMutableDictionary *dictInProgress = [dictionaryStack lastObject]; 

    if ([self.textInProgress length] > 0) { 

     [dictInProgress setObject:self.textInProgress forKey:NODE_VALUE_KEY]; 

     self.textInProgress = [NSMutableString string]; 
    } 

    [dictionaryStack removeLastObject]; 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    [self.textInProgress appendString:string]; 
} 

而只是確保你釋放它在dealloc

普羅蒂普:如果您更改屬性的相應伊娃的名稱,以及(如_textInProgress),你會得到一個編譯錯誤每個點你以前使用伊娃,所以你不會錯過任何從textInProgressself.textInProgress

+0

感謝您的評論。我已經嘗試過您的解決方案,但它仍然在同一時間向我提供相同的泄漏/錯誤。你有沒有其他的嘗試? – BarryK88 2012-02-01 19:34:52

+0

@ BarryK88:使用ARC? ;) – 2012-02-01 19:57:50

+2

嘗試用'dictInProgress'做同樣的事情並運行靜態分析器來檢查任何明顯的事情。 – 2012-02-01 20:31:29