0

我使用NSXMLParser來解析XML文檔。我有以下功能(其中包括):XML解析器中的內存泄漏

- (void) parserDidStartDocument:(NSXMLParser *)parser { 

    // Init tempString 
    tempString = [NSMutableString string]; 

}  
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 

     // save gained data for element "date" 
     if ([elementName isEqualToString:@"date"]) 
      [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey]; 

     [tempString setString:@""]; 
    } 


    // 
    // Character Handling 
    // 
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
     [tempString appendString:[[XMLParser alloc] stripUnwantedStringChars:string]]; //Just strips tabs and linebreaks and the returns the string 
    } 

tempString是一個實例變量具有以下屬性:

@property (nonatomic, retain) NSMutableString *tempString; 

tempString不具有的dealloc釋放,因爲它是一個方便的啓動方法,因此它會自動分配給自動釋放池。我也用alloc,init方法嘗試了以下,但結果相同。所以這裏是我做的:

1.)用儀器運行我的項目,讓它在啓動後立即搜索泄漏,沒有。 2.)運行一次XML解析器,檢查泄漏。沒有了。 3.)再次運行XML解析器,現在突然與[entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];一行泄漏。

我一直在尋找這些內存泄漏現在幾個小時,我忘了什麼?如果你需要更多的代碼,請讓我知道,但我認爲我的問題在這些方面。

Ps。我的檢查表明,解析器(委託)之間調用「dealloc」方法被調用,因此我認爲解析器真的被加載了兩次,而不是一次。

回答

3

您的來電:

tempString = [NSMutableString string]; 

其實不調用屬性(包裝)和retain

你應該這樣做,而不是:

self.tempString = [NSMutableString string]; 

否則你只是直接設置伊娃一個自動釋放的對象。

您不僅在某處發生泄漏,上述代碼會在某一時刻導致一些有趣的崩潰。

+0

非常感謝,這是我錯過的東西。現在它就像一個魅力:) – Robin

0

首先,我會想象這實際上應該會崩潰,因爲autoreleased可變字符串應該在您從parserDidStartDocument返回後不久發佈。它並不是那種令人關注的東西,而且你也在說謊,因爲財產在沒有被保留時會被保留下來。

然而,什麼泄漏告訴你的是,該字符串的副本已被泄露 - 泄漏您顯示對象泄漏被分配,但是這不是泄漏的原因。泄漏的原因是你沒有的代碼行應該在稍後正確釋放該字符串。由於Leaks不能指向不存在的代碼,所有它可以告訴你什麼使對象不被正確釋放。

在這種情況下,我認爲你缺少的是一個數組應該認爲是自動釋放的對象 - 所以你想說:

[entryDict setObject:[[tempString copy] autorelease] forKey:kXMLDictDateKey]; 

因爲複製還保留了副本(就像分配/初始化將)。

+0

非常感謝您的快速回答。將tempString附加到autorelease的做法是從「XML Performance」項目的Apple示例代碼中複製的。我已經添加了你建議的autorelease,但我仍然有泄漏。爲什麼tempString沒有得到適當的釋放對我來說是一個謎(我懷疑這是問題?)。我也確保「entryDict」得到釋放,它的確如此,所以我認爲這個問題真的存在於tempString中。你有什麼其他想法可能導致泄漏?非常感謝你的努力! – Robin

+0

什麼發佈entryDict?如果沒有被釋放,那麼我可以看到它會在哪裏說元素泄漏。 –

1

在你的代碼的其他錯誤是:

[tempString appendString:[[XMLParser alloc] 
    stripUnwantedStringChars:string]]; 

這種分配一個新XMLParser,從來沒有擺脫它。

+0

是的,你是對的,我忘了寫描述XMLParser是一個單身人士。因此,這不會創建XMLParser的新實例,而只是返回前一個實例。 – Robin

+0

更好的方法是遵循Apple的風格並使用'sharedInstance'類方法。用'alloc'來創建一個單例是一種非常糟糕的風格。 –

1

我想弄清楚你最終在做什麼你的任務tempString做。如果你這樣做:

self.tempString = [NSMutableString string]; 

那麼你在dealloc中釋放tempString。即使它正在自動釋放,制定者仍在保留它。