【问题标题】:How can I avoid EXC_BAD_ACCESS when checking if directories exist?检查目录是否存在时如何避免 EXC_BAD_ACCESS?
【发布时间】:2011-10-04 12:03:22
【问题描述】:

我正在构建一个应用程序,它将图像缓存在应用程序包的 Documents 目录中。为了确保目录存在,我想检查它们是否存在,如果不存在,则在应用程序启动时创建它们。

目前,我在didFinishLaunchingWithOptions: 这样做:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSArray *directoriesToCreate = [[NSArray alloc] initWithObjects:
                                    @"DirA/DirA1",
                                    @"DirA/DirA2",
                                    @"DirB/DirB2",
                                    @"DirB/DirB2",
                                    @"DirC",
                                    nil];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];

    for (NSString *directoryToCreate in directoriesToCreate) {

        NSString *directoryPath = [documentsPath stringByAppendingPathComponent:directoryToCreate];
        NSLog(directoryPath);
        if (![[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:YES]) {

            NSError *directoryCreateError = nil;
            [[NSFileManager defaultManager] createDirectoryAtPath:directoryPath
                                      withIntermediateDirectories:YES
                                                       attributes:nil
                                                            error:&directoryCreateError];


        }

    }

    [window addSubview:navigationController.view];
    [window makeKeyAndVisible];

    return YES;

}

在应用程序的第一次运行时——当不存在任何目录时——应用程序运行,目录按预期创建并且一切运行正常。

当应用程序终止并再次运行时,我在fileExistsAtPath: 调用[NSFileManager defaultManager] 时收到 EXC_BAD_ACCESS 信号。

我不明白为什么当目录不存在时它运行得很好,但当它们存在时它会崩溃。

谁能提供帮助?

【问题讨论】:

  • 你的 NSLog 应该像 NSLog(@"%@", anObject);。如果 anObject 是字符串,则指定 NSLog(anObject); 有效,因为无论如何都应该在该位置给出格式字符串。因此,它将采用 anObject 作为格式字符串。但它会崩溃,它是字符串以外的其他对象。
  • for循环之后尝试retainpathsdocumentsPath对象和release它们。

标签: objective-c ios cocoa-touch exc-bad-access nsfilemanager


【解决方案1】:

您以错误的方式使用检查功能。第二个参数必须是指向布尔变量的指针,该变量将在函数调用后填充:

你正在使用这样的函数:

[[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:YES];

但是函数应该这样使用:

BOOL isDir;
[[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:&isDir];

if (isDir) { // file exists and it is directory.

【讨论】:

  • 这解释了为什么使用不带isDirectory 参数的函数有效——感谢您解释原因。
  • +1 我真的很讨厌人们不关心编译器警告。它直接指向问题。
  • 我确实关心编译器警告——只是在我对 iOS 进行修补的早期阶段,我经常不明白它们的含义。
  • @abitgone 是的,它们可能很难理解——但这真的很值得。它们通常是解决问题的最简单方法,并且可以尽早进行。在这里,消息告诉您参数类型不匹配。
  • 我根本没有收到编译器警告...会为我省去很多麻烦!
【解决方案2】:

isDirectory 是一个 (BOOL*),用于返回一个布尔值,描述路径是否指向目录。您正在传递一个 BOOL。

目录存在不崩溃的原因是目录不存在时没有设置值。

【讨论】:

  • fileExistsAtPath:directoryPath isDirectory:YES 更改为 fileExistsAtPath:directoryPath 似乎可以解决问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 2012-09-12
  • 2011-02-15
  • 2023-02-22
  • 2020-03-18
  • 1970-01-01
相关资源
最近更新 更多