无法释放NSData对象的内存

我是xcode/cocoa的新手,甚至是objective-c因此我的问题可能是愚蠢的。我试图写一个程序,将文件夹中的文件哈希。我环顾四周,发现了一种通过NSData对象加载文件的方法,而不是使用CC_SHA512来散列它的字节。 如果我尝试哈希几个文件,我注意到我的内存耗尽。使用运行 - >性能工具,我可以找出我的问题。我创建的所有NSData对象仍在内存中。我尝试使用release/dealloc自动释放和manualy释放。没有什么工作。 我的编译器设置是标准的,有一个例外,我选择Objective-C垃圾收集=必需。 也许有人可以告诉我我做错了什么。 这是代码:

-(FileHash*) hashFileByName :(NSString*) filePath{
//NSData* inputData = [inputStr dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(filePath);
    NSData* inputData = [[NSData dataWithContentsOfFile:filePath] autorelease];
    unsigned char outputData[CC_SHA512_DIGEST_LENGTH];
    CC_SHA512([inputData bytes], [inputData length], outputData);
NSMutableString* hashStr = [NSMutableString string];
    int i = 0;
    for (i = 0; i < CC_SHA512_DIGEST_LENGTH; ++i)
        [hashStr appendFormat:@"%02x", outputData[i]];
//NSLog(@"%@ hash : %@",filePath,hashStr);
FileHash *hash = [[[FileHash alloc]init]autorelease];
    [hash setFileHash:hashStr];
    [hash setFilePath:filePath];
    [inputdata release];
    [inputdata dealloc];
    return hash;    
}
-(NSMutableArray*) hashFilesInDirectory:(NSString*) pathToDirectory:(Boolean) recursive : (IBOutlet id) Status : (Boolean*) BreakOperation{
NSGarbageCollector *collect = [NSGarbageCollector defaultCollector];
NSMutableArray *files;
        files = [[self listFilesOnlyRecursive:pathToDirectory] autorelease];
NSMutableArray *hashes = [[[NSMutableArray alloc]init]autorelease];
for (NSString *file in files) {
[hashes addObject: [self hashFileByName:file]]; 
        [collect collectExhaustively];
    }
return hashes;
}
-(NSMutableArray*) listFilesOnlyRecursive : (NSString*) startDir {
NSMutableArray *filelist = [[[NSMutableArray alloc] init]autorelease];
//Inhalt eines Verzeichnisses auflisten (unterverzeichnisse werden ignoriert
    NSFileManager *manager = [[NSFileManager defaultManager]autorelease];
NSDirectoryEnumerator *enumerator = [manager enumeratorAtPath:startDir];
    int count = 0;
    id file;
    while (file = [enumerator nextObject])
    {
//      file = [[[[startDir stringByAppendingString:@"/"]autorelease] stringByAppendingString:file] autorelease
        //              ];
        file = [NSString stringWithFormat:@"%@/%@",startDir,file];
        BOOL isDirectory=NO;
        [[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory];
        if (!isDirectory){
            [filelist addObject:file];
            //printf("\n:%s:\n",[file UTF8String]);
            count++;
        }
}
    NSLog(@"Es waren %i files",count);
    return filelist;
}
所有这一切都始于
int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    //return NSApplicationMain(argc,  (const char **) argv);
    MemoryLeakTest *test = [[[MemoryLeakTest alloc]init]autorelease];
    [test hashFilesInDirectory:@"/huge directory/" :YES :nil :nil];
    [pool drain];
    [pool release];
    [pool dealloc];
}
也许有人有个主意。 比你提前:) NUBUS
已邀请:

saut

赞同来自:

有几件事:

NSData* inputData = [[NSData dataWithContentsOfFile:filePath] autorelease];
如果你想让它保持在当前方法执行之外,你必须保留它(这有点过于简单,但对你的例子来说是合理的)。由于dataWithContentsOfFile:不包含alloc,copy或new,因此除非您明确保留它,否则您不负责释放它。鉴于您只在函数中本地使用它,您不需要保留它。因此,只需使用以下内容,不要在其上调用release/autorelease或dealloc:
NSData* inputData = [NSData dataWithContentsOfFile:filePath];
此外,您从不手动解除分类。只需根据需要发布/自动发布它们。 dealloc将根据需要调用。
[inputData dealloc]; // don't do this explicitly
你肯定需要阅读Cocoa Memory Management document。它会清理很多。

taut

赞同来自:

在阅读了我以前所知的MemoryManagement文档之后。所以我开始尝试和错误。我试过像释放NSData对象直到retaincount为0 ..和和。比我找到了一个有效的解决方案 我不得不自己初始化NSData对象,并将其设置为自动释放(我自己无法释放它,因为在我调用init之后,有一个2的重复并试图释放它2次导致崩溃 blabla在这里我的解决方案:

-(FileHash*) hashFileByName :(NSString*) filePath{
NSAutoreleasePool *innerpool = [[NSAutoreleasePool alloc]init];
//NSData* inputData = [inputStr dataUsingEncoding:NSUTF8StringEncoding];
    NSData* inputData = [[[NSData alloc]initWithContentsOfFile:filePath] autorelease];
    unsigned char outputData[CC_SHA512_DIGEST_LENGTH];
    CC_SHA512([inputData bytes], [inputData length], outputData);
NSMutableString* hashStr = [NSMutableString string];
    int i = 0;
    for (i = 0; i < CC_SHA512_DIGEST_LENGTH; ++i)
        [hashStr appendFormat:@"%02x", outputData[i]];
[innerpool drain];
//NSLog(@"%@ hash : %@",filePath,hashStr);
FileHash *hash = [[[FileHash alloc]init]autorelease];
    [hash setFileHash:hashStr];
    [hash setFilePath:filePath];
return hash;    
}
我希望这会帮助别人:) 谢谢您的回答。 ps:也许soneone可以告诉我为什么我自己无法释放它或为什么保留计数为2。

要回复问题请先登录注册