在分配NSString时获取EXC_BAD_ACCESS

时间:2011-03-02 10:22:30

标签: iphone objective-c exc-bad-access

我写了一个函数来将一个字符串返回到一个目录路径。我得到一个EXC_BAD_ACCESS,我认为这个函数是原因。我需要保留nsstring吗?

-(void) getRemoteFiles:(NSMutableArray *) M
{
    [self createFileToAppDirectory];

    if (!networkqueue) {
        networkqueue:[[[ASINetworkQueue alloc] init] autorelease];
    }

    [[self networkQueue] cancelAllOperations];

    [self setNetworkQueue:[ASINetworkQueue queue]];
    [[self networkQueue] setDelegate:self];
    [[self networkQueue] setRequestDidFinishSelector:@selector(requestFinished:)];
    [[self networkQueue] setRequestDidFailSelector:@selector(requestFailed:)];
    [[self networkQueue] setQueueDidFinishSelector:@selector(queueFinished:)];


    int i;

    for (i=0; i<[M count]; i++) {
        NSString *url=[M objectAtIndex:i];
        NSString* theFileName = [url lastPathComponent];
        NSString *safestring=[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        if ([theFileName isEqualToString:@"nothing"]==NO) {

            ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:safestring]];
            //think this is causing the problem
            NSString *savepath=[self getDirectoryPathForFileName:theFileName];
            //[request setDownloadDestinationPath:savepath];
            [[self networkQueue] addOperation:request];
        }

    }

    [[self networkQueue] go];
    //error thrown after this point


}
-(NSString *)getDirectoryPathForFileName:(NSString *)filename

{
    NSFileManager *filemgr;
    NSArray *dirPaths;
    NSString *docsDir;
    NSString *newDir;
    BOOL isDir;


    filemgr =[NSFileManager defaultManager];
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];

    newDir = [docsDir stringByAppendingPathComponent:@"remix_data"];
    if ([filemgr fileExistsAtPath:newDir isDirectory:&isDir]==NO) {
        NSLog(@"dir should exist but does not... go funt dat");
    }

    NSString *localFilePath = [newDir stringByAppendingPathComponent:filename];
    [filemgr release];
    [docsDir release];
    [newDir release];
    return localFilePath;
}

3 个答案:

答案 0 :(得分:2)

不,你真的过度释放了。在getDirectoryPathForFileName中,您将发布docsDir(例如),尽管您从未保留过它。您将它从dirPaths数组中拉出来,这不会增加保留计数。通过释放它,你将减少保留计数,可能为零,这将解除串,而阵列仍然认为它持有它。下次数组使用该字符串执行某些操作时,您的应用程序将崩溃。只需删除docsDir和newDir的发布调用,你应该很好......

答案 1 :(得分:1)

正如有人有EXC_BAD_ACCESS问题一样,我推荐NSZombie。在您的特定情况下,很容易看出它崩溃的原因,因为您在没有首先分配或保留它的情况下发布了东西。你应该只发布你自己分配或保留的东西。

如果您将来遇到EXC_BAD_ACCESS问题,这不容易弄明白,以下是如何使用NSZombie:

要激活NSZombie,请执行以下操作:

  1. 获取可执行文件的信息。
  2. 转到参数选项卡。
  3. 在“要在环境中设置的变量:”部分添加:
  4. 名称:NSZombieEnabled 价值:是

    然后像往常一样运行您的应用程序,当它崩溃时,它应该告诉您哪个已解除分配的对象收到了释放消息。

答案 2 :(得分:-1)

是的,最好保留字符串并在使用后释放它。此外,不建议释放字符串docsDirnewDir,因为您没有分配它们。它们是自动释放对象。