我正在使用NSFileManager
的{{1}}方法来计算某个目录下的文件大小。
enumeratorAtPath
结果如下:
有时像这样:
用于什么内存?为什么甚至在外面添加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);
没有效果?
答案 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
指令范围之外的主自动释放池中,它们只会坐到该池清空。但是,你仍然在循环中使用自己的自动释放池做了一件好事。