2017-09-23 157 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

相关问题