使用filemanager迭代dirs占用了相当多的内存

时间:2013-07-09 03:15:35

标签: ios objective-c memory nsfilemanager

我正在使用NSFileManager的{​​{1}}方法来计算某个目录下的文件大小。

enumeratorAtPath

结果如下:

take many memory during while loop

有时像这样:

no returning memory

用于什么内存?为什么甚至在外面添加NSString *iterDir = @"/path/to/dir/"; NSFileManager *fm = [[NSFileManager alloc] init]; NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath:iterDir]; NSString *file; BOOL isDir; long long fileSize = 0; while (file = [dirEnum nextObject]) { @autoreleasepool { file = [iterDir stringByAppendingString:file]; if ([fm fileExistsAtPath:file isDirectory:&isDir]) { if (!isDir) { NSError *error; NSDictionary *attributes = [fm attributesOfItemAtPath:file error:&error]; if (!error) { fileSize += [attributes[@"NSFileSize"] doubleValue]; } } } } } NSLog(@"fileSize:%lld", fileSize); 没有效果?

1 个答案:

答案 0 :(得分:0)

即使替换了有效的目录路径,我也无法按照提供的方式运行示例。您的代码有一些问题。以下是您需要做出的一些更改。一个是这一行:

file = [iterDir stringByAppendingString:file];

真的应该改为:

file = [iterDir stringByAppendingPathComponent:file];

后者更安全,因为无论您的目录路径是否以/结尾,它都会正确附加路径。 (在我的情况下,您的原始版本失败,因为我使用[@"~/Desktop" stringByExpandingTildeInPath]来获取我的目录路径;这会生成一个没有尾随/的路径。)

然后在你的循环中,你在堆栈上分配一个未初始化的变量error,通过引用传递它,然后询问它是否是nil。这是一个错误的问题,因为除非方法返回nil(或error,具体取决于方法),否则无法保证NO的值。您应该询问attributes是否nil,并NULL传递error,因为您似乎对它不感兴趣。总而言之,改变一下:

NSError *error;
NSDictionary *attributes = [fm attributesOfItemAtPath:file error:&error];
if (!error) {

到此:

NSDictionary *attributes = [fm attributesOfItemAtPath:file error:NULL];
if (attributes != nil) {

我保证,修复第二个问题意味着您的结果会更加一致。同时,当我运行代码时,我得到的结果看起来可能是NSLog()语句中的有效值。

什么都没有,你也可以使用快速枚举你的循环。而不是:

while (file = [dirEnum nextObject]) {

你可以改用:

for (file in dirEnum) {

现在提出原始问题。你的分配内存膨胀的原因是你的包含文件名的字符串被分配到你的@autoreleasepool指令范围之外的主自动释放池中,它们只会坐到该池清空。但是,你仍然在循环中使用自己的自动释放池做了一件好事。