【问题标题】:Checking if a .nib or .xib file exists检查 .nib 或 .xib 文件是否存在
【发布时间】:2010-10-29 18:01:48
【问题描述】:

在尝试使用 initWithNibName:bundle: 或类似方法加载之前检查 Nib 或 Xib 文件是否存在的最佳方法是什么?

【问题讨论】:

  • 为什么会丢失笔尖?尤其是在 iPhone 应用程序中;这不像用户可以在您签名的应用程序包中乱七八糟。 (也许是越狱,但即便如此,如果用户从应用程序内部删除内容,他们也应该预料到会崩溃。)
  • 你说得对。我有一个相当复杂的界面层次结构,一些笔尖还没有完成。我想“捕获”任何未找到并显示“未实施”警报,这意味着如果我点击错误的按钮,我可以发送演示并且不会使模拟器崩溃。
  • @PeterHosey 在设计库/框架时怎么样?您不知道用户的应用程序中包含和不包含的内容。最好在那里检查一下。
  • @Kevin:为什么这会是库/框架的任何业务?
  • @PeterHosey 这样您就可以优雅地返回错误或抛出异常,而不仅仅是让应用程序崩溃...

标签: iphone objective-c xcode nib


【解决方案1】:

我在这里看到了两种解决方案。

您可以调用 initWithNibName:bundle: 并在异常失败时捕获异常(我喜欢这个想法,感觉很健壮)。您可能希望验证该异常实际上是“找不到文件”异常,而不是“内存不足”异常。

或者,您可以先检查 nib 是否存在,使用 NSBundle 的 pathForResource:ofType:,对于不存在的文件返回 nil。

【讨论】:

  • initWithNibName:bundle: 不会在文件不存在时抛出异常,您只会在尝试将其与 pushViewController:animated: 之类的东西一起使用时遇到问题
  • initWithNibName:bundle 如果找不到 nib 则返回 nil;所以请检查一下。
  • @Abizern 我是这么想的,但它似乎不起作用,尽管文档说如果没有找到 nib 文件它会返回 nil 我总是得到一个分配。而且我已经清理了项目,所以没有缓存问题......
  • @Emilio 这表明它正在寻找一个笔尖。
  • @Emilio 是正确的,initWithNibName:bundle: 似乎返回了一个有效的对象,即使你传递给它一个总垃圾名称。
【解决方案2】:

#define AssertFileExists(path) NSAssert([[NSFileManager defaultManager] fileExistsAtPath:path], @"Cannot find the file: %@", path)
#define AssertNibExists(file_name_string) AssertFileExists([[NSBundle mainBundle] pathForResource:file_name_string ofType:@"nib"])

这里有一组宏,您可以在尝试加载 .xib.nib 之前调用它们,它们将有助于识别丢失的文件并吐出有用的信息来说明究竟丢失了什么。

解决方案

Objective-C

if([[NSBundle mainBundle] pathForResource:fileName ofType:@"nib"] != nil) 
{
    //file found
    ...
}

请注意,文档指出ofType: 应该是文件的扩展名。但是,即使您使用的是 .xib,您也需要传递 `@"nib" 否则您会得到一个假阴性。

斯威夫特

guard Bundle.main.path(forResource: "FileName", ofType: "nib") != nil else {
       ...
    }

(参见:touti 的原始答案:https://stackoverflow.com/a/55919888/89035

【讨论】:

  • 很好的解决方案,但请考虑编辑您的答案:关于 ofType: 的文档实际上是正确的,并且参数 可能 是文件的扩展名(您实际上可以把pathForResource: 中的整个文件名和ofType: 中的 nil 并且一切都会正常工作,尽管我不知道这是否是一个好习惯)。 xib/nib 差异的原因是 xib 文件实际上是在应用程序中预处理并打包为 nibpathForResource:ofType: 按指定工作;-)(只需检查 .app 内容如果你不相信我)
  • PS:刚刚看到答案时间戳,您从 2009 年开始就开始使用移动设备了?! -哇-
  • 如果您想寻找故事板,只需将ofType: 参数更改为“storyboardc”。看起来像是一个错字,但那是捆绑包中的扩展故事板。
  • 哦!为什么苹果让这变得如此混乱?出于历史原因?
【解决方案3】:

快速解决方案:

guard Bundle.main.path(forResource: "FileName", ofType: "nib") != nil else {
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多