我不太熟悉Objective-C,所以請原諒我,如果這是一個愚蠢的問題。我創建了一個後臺線程來解析目錄中存在的文件列表,目錄中的文件可以隨時更改。iOS - 調用contentsOfDirectoryAtPath在循環中泄漏內存
我呼籲在循環的每次迭代「contentsOfDirectoryAtPath」,我突然分配去了300MB。我無法弄清楚如何讓ARC釋放返回的數組。有人可能會指出我在這裏的正確方向嗎?你可以看到,我試圖通過設置'files'釋放數組爲零,但它不起作用。
我不太熟悉Objective-C,所以請原諒我,如果這是一個愚蠢的問題。我創建了一個後臺線程來解析目錄中存在的文件列表,目錄中的文件可以隨時更改。iOS - 調用contentsOfDirectoryAtPath在循環中泄漏內存
我呼籲在循環的每次迭代「contentsOfDirectoryAtPath」,我突然分配去了300MB。我無法弄清楚如何讓ARC釋放返回的數組。有人可能會指出我在這裏的正確方向嗎?你可以看到,我試圖通過設置'files'釋放數組爲零,但它不起作用。
你怎麼創建這個線程? NSThread? NSOperation和NSOperationQueue? GCD?
對於NSThread和的NSOperation,你應該創建自己的自動釋放池設置線程的一部分。這樣臨時對象在該線程內得到正確管理。
我相信GCD會爲您處理這些細節。
在Objective C中的新版本(目標C 2.0,我相信),你應該使用新的語法
@autoreleasepool
{
//Code to use a local autorelease pool
}
對於生成一噸的臨時對象的循環,你可以創建任何一個地方自動釋放池代碼塊。你可以重構你的代碼是這樣的:(從而釋放在該迭代創建的臨時對象)
while(1)
{
@autoreleasepool
{
NSArray *files = [nfm contentsOfDirectoryAtPath:dataDir error:nil];
/*
if(files == nil)
break;
if([files count] <= 0)
{
files = nil;
[NSThread sleepForTimeInterval: 5.0f];
continue;
}
if(![ViewController obtainLock])
{
files = nil;
continue;
}
*/
//[ViewController releaseLock];
files = nil;
}
}
這會導致它以創建循環的每個迭代一個新的自動釋放池,並在最後排幹
順便說一句,如果你使用NSThread,不要。學習如何使用GCD代替。 GCD(Grand Central Dispatch)比NSThread更有效地利用系統資源。 NSThread基於POSIX線程,這些線程創建起來非常昂貴,並且在應用程序的生命週期中將設備上的物理內存綁定在一起。
NSOperationQueues在最近的OS版本被重構使用GCD在幕後,所以他們也同樣有效的內部,雖然難比GCD使用的大部分事情。
謝謝你的答案,添加一個自動釋放池做的伎倆。我正在使用NSThread創建此線程。你說NSThread在應用程序的生命週期中佔用了物理內存,但是如果這個線程應該運行在應用程序的生命週期,這真的很重要嗎?無論哪種情況,我都會看看GCD--感謝指針! – Gogeta70
那麼,我認爲答案顯而易見。看看documentation。
許多程序創建的自動釋放臨時對象。這些 對象將添加到程序的內存佔用空間直到 塊的末尾。在許多情況下,允許臨時對象累積 ,直到當前事件循環迭代結束時,不會導致 過多的開銷;但是,在某些情況下,您可能會創建大量的臨時對象,這些臨時對象會大大增加內存佔用量,並且希望更快地處理這些對象。在這些 後面的情況下,您可以創建自己的自動釋放池塊。在塊的末尾 處,釋放臨時對象,這通常會導致它們的釋放,從而減少程序的內存佔用量 。
而你可以看到這個question。
因此,解決方案使用您的@autoreleasepool{}
,因爲您正在創建許多臨時對象。
你使用ARC項目嗎? – Joey
請注意:[NSFileManager defaultManager]不是線程安全的,請改用[[NSFileManager alloc] init]。 – San
@San我會閱讀[文檔](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsfilemanager_Class/Reference/Reference.html#//apple_ref/doc/uid/20000305-SW19),然後再進行索賠。 – CodaFi