2010-08-11 50 views
0

我一直在做一些測試,和我的需求之一就是閱讀從不同的XML文件的數據和堆疊在一起它在一個單一的文件。雖然我已經成功地做到這一點,內存消耗似乎是任務相當大,iPhone模擬器甚至沒有提升內存警告,但我不認爲真正的iPhone會容忍這樣的(我沒有一個設備在這裏嘗試它,所以我主要從我讀過的內容中猜測)。
代碼(的主要部分)是這樣的:優化內存消耗時逐漸寫入文件

Boolean success = [fileManager createFileAtPath:documentsPath contents:nil attributes:nil]; 
[fileManager release]; 

if (success) { 
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:documentsPath]; 
    for (int i = 0; i < 100; i++) { 

     NSString *path = [[NSBundle mainBundle] pathForResource:@"mensagem_de_arquivo" 
                 ofType:@"xml"]; 
     NSData *data = [NSData dataWithContentsOfFile:path]; 
     GDataXMLDocument *xml = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; 
     NSArray *tokens = [xml nodesForXPath:@"//message/data" error:nil]; 
     if (tokens.count > 0) { 
      GDataXMLElement *token = (GDataXMLElement *)[tokens objectAtIndex:0]; 
      [fileHandle writeData:[[token stringValue] dataUsingEncoding:NSASCIIStringEncoding]]; 
     } 
     [xml release]; 
    } 

使用「建立與分析」命令,讓我無泄漏或任何東西,並建立當代碼沒有提出警告,但仍,內存消費量介於50到70mb之間(僅考慮實時字節數,總體上幾乎翻番)。
的想法顯然不是閱讀100次相同的文件,但作爲測試數據比就足夠多,因爲代碼有剛剛從XML文件中讀取內容,並將它們發送到他們收到的順序文件。

有沒有什麼辦法來強制分配新的之前一些臨時對象的版本,我可以嘗試重用一些變量,來幫助我的任何想法保持這種控制下的真正的歡迎。

編輯 - 只是爲了讓事情變得有趣一點:最好保留一個解析器來讀寫,最好的做法是堅持使用GDataXML,或者如果需要更改,使用KissXML,TinyXML的或的libxml - DOM,這似乎都吸了一點點更多的內存,作爲所述here,所以如果有強制執行的內存釋放這將是最好的方式。

感謝提前:)

回答

1

其實,這是一個很簡單的解決方案。

我只需要實例化一個AutoReleasePool並在循環結束時將其排空。
像這樣:

for (int i = 0; i < 100; i++) { 
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init]; 
    //... do everything I've done before... 
    [pool drain]; 
} 

這被迫釋放對象標記爲自動釋放裏面的,這只是被釋放它的結束後,因爲它是意料之中的,沒有一切干擾,所以沒有對象被釋放實例在他們應該之前。
在循環過程中,內存消耗從60〜80mb的空閒時間下降到了1,6mb,並在回到同一個600kb之後(這是一個虛擬應用程序,完成了這一步)。

我還是會離開這個問題打開了一會兒,如果有人有更好的想法,但就目前而言,似乎這將是這樣:)

0

呀,你已經通過閱讀這一切到一個NSData,然後解析成GDataXMLDocument一個DOM「加倍」它。如果您希望瀏覽大量這樣的XML數據,循環播放多個文件等,則應該使用consider SAX based parsing instead,並直接從文件中流式傳輸,而不是將其預先加載到NSData中。通過這種方式,您不必「釋放臨時對象」,因爲您只需提取需要的信息,並將其解析出來。

+0

是啊,「翻番」是一個偉大的蔣梅鑫,改變到SAX爲基礎的解析幾乎減半內存消耗,能夠使用38mb完成相同的操作,但完成了近5倍。我將文件句柄作爲私有變量保存在我的委託上,並直接從「foundCharacters」方法寫入文件,考慮到我只需要從我的文件中獲取單個節點中的內容,是否還有更好的方法呢? – wintermute 2010-08-12 14:48:55

+0

一旦找到該節點,是否有任何理由保留該文件或XML?我會將所需的任何信息複製到節點外,而不是保留該節點,然後處理與該XML文件有關的任何事情。 – jbm 2010-08-12 17:35:31