2017-09-23 91 views
2

有沒有人有一個想法,爲什麼下面的代碼使用荒謬的4.75 GB的內存?爲什麼FileManager.enumerator使用荒謬的內存量?

有什麼更好的方法來循環文件系統中的所有文件? (我試圖找到驅動器上的最大的文件)

let filemanager:FileManager = FileManager() 
let root = "/" 
let files = filemanager.enumerator(atPath: root) 
while let element = files?.nextObject() { 
    // do nothing 
} 

注:也有我的文件系統(沒有什麼特別)400K的文件。代碼是順序的,所以理論上它甚至不應該依賴於文件的數量。

回答

3

我用內存圖暫停了它,它顯示了從fileSystemRepresentation(withPath:)分配的荒謬數量的NSConcreteData實例。

該文檔頁面指出,它是一個只適用於當前自動釋放池的指針。這表明了一個解決方案:我們只需要將nextObject()調用放入其自己的autorelease池中。

這個程序,例如,保持穩定在11.0 MB:

var done = false 
while !done { 
    autoreleasepool { 
     let element = files?.nextObject() 
     done = (element == nil) 

     // do nothing 
    } 
} 

它看起來像雨燕的while let語法放入while循環的情況下的自動釋放池的結合,讓每一個元素仍然保留,直到整個循環完成。

通過強制枚舉器的對象進入我們自己的autorelease池,我們可以確保它在後續迭代過程中不被保留。

編輯:由於autoreleasepool只是一個FUNC,我可以寫這個更簡潔:

while let element = autoreleasepool(invoking: { files?.nextObject() }) { 
    // do nothing 
} 
+0

你是100%正確。雖然我也在玩'autorelease',但我把它放在循環中,這就是爲什麼它沒有幫助。你的解決方案簡單地工作。謝謝!! – adamsfamily