2013-06-30 33 views
2

我有一個Cocoa程序正在編輯數百(有時是數千)第三方文件,我想爲最終用戶創建一個日誌類型的輸出(儘管我不需要像時間戳這樣的東西) 。目前,我只是將字符串附加到插座上:在內存中保留長字符串的最佳方式是什麼? (Cocoa)

@property (unsafe_unretained) IBOutlet NSTextView *finalText; 
... 
self.finalText.string = [self.finalText.string stringByAppendingFormat:@"Final results:\n"]; 

但這是非常低效的。當我在上面的代碼(所有註釋)關閉的700個文件上運行代碼時,需要4秒鐘執行,打開上面的代碼需要40秒來創建必要的8000行輸出。噢,我提到Xcode說在處理過程中我的內存使用量超過了2GB?哎呀!

據我所知,我所做的是效率低下,但我不知道最有效的方法。創建最終用戶最終可以看到的8000行文本的最佳方式是什麼?會像Lumberjack是最好的解決方案?

+0

需要查看更多代碼才能評論效率。如果你在主線程上做所有事情,你可能會阻止。 – uchuugaka

+0

如何創建一個字符串,當它達到一定的大小,你把它寫入一個文件,然後提供給用戶一個文件名來看待? – 7stud

+0

我看到有人建議在另一個問題上使用textStorage,但我需要使用格式(向輸出添加變量),我沒有看到使用textStorage項目的格式。 –

回答

0

[self.textView.textStorage appendAttributedString:...]

這將大大減少工作。另外,將它封裝在@autoreleasepool中以及時清理臨時對象。

+0

謝謝!我最終創建了一些textStorage變量,這些變量是我在代碼末尾轉儲到textView中的。現在,當我創建所需的輸出時,對時間或內存使用情況沒有明顯的影響! –

1

伐木工人非常適合伐木。另外,您應該使用NSMutableString來避免一次又一次創建相同字符串的副本。

+0

我讓伐木工人工作,但我不知道如何在.log文件中讀回(如何在用戶的HD上找到它)。此外.log文件包含時間戳等,有沒有辦法不包括? –

-1

你應該使用這樣的:

NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 

這將需要一個或兩個毫秒與300GB的文件,和整個文件,如果有足夠的可用RAM只會加載到RAM中。如果沒有足夠的可用RAM,它只會載入您實際讀取的文件部分,並且啓發式地/預測性地讀取操作系統認爲您將要讀取的部分。

NSString是CFString的便捷包裝。如果您下拉到較低級別的CFString API,您將能夠編寫代碼,以便使用更少的RAM(例如,通過部分解碼大文件)。從文件中部分讀取字符串很複雜,您需要了解UTF-8的工作方式,並確保您不會將數據通過UTF-8序列中途切斷。如果你可以用NSString獲得可接受的性能,我會盡量避免使用CFString。

另外,你有一個forwhile循環迭代所有的文件?請確保你在你的循環中的 「自動釋放」 池:

NSArray *urls = <# An array of file URLs #>; 
for (NSURL *url in urls) { 

    @autoreleasepool { 
     NSError *error; 
     NSString *fileContents = [NSString stringWithContentsOfURL:url 
             encoding:NSUTF8StringEncoding error:&error]; 
     /* Process the string, creating and autoreleasing more objects. */ 
    } 
} 

(從http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-SW2

+0

謝謝,請關注一下。爲了清楚我發送給最終用戶的信息與文件中的內容沒有直接關係,IE:我正在閱讀文件,對文件做些什麼,然後告訴用戶我對文件做了什麼。沒有向用戶顯示文件中的內容。 –

+0

你確定嗎?該文檔沒有提供任何建議,-initWithContentsOfURL:將檢查可用RAM的數量,但它不指望它 –

+0

是的,我敢肯定 - 我已經測試過它。當我用一個不適合RAM的文件初始化一個NSData對象時,創建該對象需要幾分之一毫秒(如果讀取整個文件需要幾分鐘)。我可以立即訪問文件的一部分。如果該文件適合內存(也許它只有8GB,我的系統有12GB),那麼我的應用程序將使用這麼多。它被映射爲虛擬內存/交換,並且內核試圖將這些文件保存在RAM中,但如果其他任何內容都需要RAM,則將它們(基於最近最少使用的文件區域)進行分塊。 –

相關問題