gpt4 book ai didi

ios - 使用文件管理器迭代目录占用大量内存

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:21:13 28 4
gpt4 key购买 nike

我正在使用 NSFileManagerenumeratorAtPath 方法来计算特定目录下的文件大小。

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);

结果是这样的:

take many memory during while loop

有时是这样的:

no returning memory

内存有什么用?为什么在外面加了一个@autoreleasepool也没有效果?

最佳答案

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

file = [iterDir stringByAppendingString:file];

真正应该改为:

file = [iterDir stringByAppendingPathComponent:file];

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

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

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 指令的范围之外分配到主自动释放池中,它们将一直坐在那里直到该池清空。但是,在循环内使用您自己的自动释放池仍然是一件好事。

关于ios - 使用文件管理器迭代目录占用大量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17539297/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com