我编写了一个方法(getDirTree1),它使用推荐的类NSDirectoryEnumerator和方法nextObject列出了根目录下的所有目录。但是当它运行不可接受时使用了大量内存(主要是私有类NSPathStore2):
-(void) getDirTree1:(NSString*)directoryPath {
NSDirectoryEnumerator *dirEnum = [self->fileManager enumeratorAtPath:derectoryPath];
NSString *filePath;
NSString *fullFilePath;
while ( ( filePath = [ dirEnum nextObject ] ) != nil ) {
fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ];
NSLog( @"%@ \n", fullPath );
}
}
假设这是因为对象NSDirectoryEnumerator,我重写了方法(getDirTree2)。现在使用递归,NSArray类和objectEnumerator方法。 但是再一次使用了很多记忆。
-(void) getDirTree2:(NSString*)directoryPath {
NSArray *contents = [ self->fileManager contentsOfDirectoryAtPath:directoryPath error:NULL ];
NSEnumerator *enumeratorContent [ contents objectEnumerator ];
NSString *file;
BOOL fileIsDirectory = FALSE;
while ( ( file = [ enumeratorContent nextObject ] ) ) {
NSLog( @"%@ \n", [ directoryPath stringByAppendingPathComponent: file ] );
if ( [ self->fileManager fileExistAtPath:[ directoryPath stringByAppendingPathComponent:file ] isDirectory:&fileIsDirectory ] && fileIsDirectory )
[ self getDirTree2:[ directoryPath stringByAppendingPathComponent: file ] ];
}
}
我错过了(也许我必须dealloc /保留一些对象)以及如何做得更好。 感谢。
答案 0 :(得分:4)
[directoryPath stringByAppendingPathComponent:filePath];
返回一个自动释放的对象。由于它发生在这样一个紧密的循环中,所有这些对象都在加起来并导致大量的内存占用。你需要做的就是更频繁地摆脱它们。您可以将方法更改为不使用自动释放的方法,或者您可以创建自己的紧密自动释放池,如下所示:
while ( ( filePath = [ dirEnum nextObject ] ) != nil ) {
NSAutoreleasePool* pool = [NSAutoreleasePool new];
fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ];
NSLog( @"%@ \n", fullPath );
[pool drain];
}
这将确保您不再需要的所有内容尽快发布,避免在循环过程中构建对象。
(有趣的旁注:NSPathStore2
是一个与用于存储路径类型字符串的NSString
(类集群)相关的私有类。这就是我知道哪种方法有问题的方法。)< / p>
答案 1 :(得分:4)
对于使用自动引用计数的任何人,如果以下(应该相当于 andyvn22 的ARC答案)不适合您:
while ( ( filePath = [ dirEnum nextObject ] ) != nil ) {
@autoreleasepool {
fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ];
NSLog( @"%@ \n", fullPath );
}
}
我能够通过这样做来解决它
filePath = [ dirEnum nextObject ] );
while ( filePath != nil ) {
@autoreleasepool {
fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ];
NSLog( @"%@ \n", fullPath );
filePath = [ dirEnum nextObject ] );
}
}
代码不尽如人意,但节省的内存是。
更新:最近再次出现问题,更有效的是:
file = [dirEnum nextObject];
while (file) {
@autoreleasepool {
fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ];
NSLog( @"%@ \n", fullPath );
filePath = [ dirEnum nextObject ] );
}
}
答案 2 :(得分:-1)
轻松使用NSDirectoryEnumerator
作为documented here和shown here