我编写了一个方法(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 ] ]; } }我错过了什么(也许我必须释放/保留一些物体)以及如何做得更好。 谢谢。
I wrote a method(getDirTree1) that makes listing all directories from the root, using the recommended class NSDirectoryEnumerator and method nextObject. But while it was running unacceptably used a lot of memory (mainly private class 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 ); } }Assuming that this is because the object NSDirectoryEnumerator, I rewrote the method(getDirTree2). Now using the recursion, NSArray class and objectEnumerator method. But once again used a lot of memory.
-(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 ] ]; } }What I missed(maybe I must dealloc/retain some objects) and how to do better. Thanks.
最满意答案
[directoryPath stringByAppendingPathComponent:filePath]; 返回一个自动释放的对象。 由于它发生在这样一个紧密的循环中,所有这些对象都在加起来并导致大量的内存占用。 你需要做的就是更频繁地摆脱它们。 您可以将您的方法更改为不使用autorelease的方法,或者您可以创建自己的紧密autorelease池,如下所示:
while ( ( filePath = [ dirEnum nextObject ] ) != nil ) { NSAutoreleasePool* pool = [NSAutoreleasePool new]; fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ]; NSLog( @"%@ \n", fullPath ); [pool drain]; }这将确保在您不再需要时立即释放所有内容,从而避免在循环期间堆积对象。
(有趣的旁注: NSPathStore2是一个与NSString (它是一个类集群)相关的私有类,用于存储路径类型的字符串。这就是我知道哪种方法有问题的方法。)
[directoryPath stringByAppendingPathComponent:filePath]; returns an autoreleased object. Since it's happening inside such a tight loop, all these objects are adding up and causing the large memory footprint in question. All you have to do to fix it is get rid of them more often. You can change your method to something that doesn't use autorelease, or you could just create your own, tight autorelease pool, like this:
while ( ( filePath = [ dirEnum nextObject ] ) != nil ) { NSAutoreleasePool* pool = [NSAutoreleasePool new]; fullFilePath = [ directoryPath stringByAppendingPathComponent:filePath ]; NSLog( @"%@ \n", fullPath ); [pool drain]; }This will ensure that everything's released as soon as you no longer need it, avoiding the buildup of objects during the loop.
(Interesting sidenote: NSPathStore2 is a private class related to NSString (which is a class cluster) used to store path-type strings. That's how I knew which method was at fault.)
更多推荐
发布评论