如何为本地化应用加载 XIB?

Posted

技术标签:

【中文标题】如何为本地化应用加载 XIB?【英文标题】:How are XIBs loaded for localized apps? 【发布时间】:2011-05-13 07:22:22 【问题描述】:

在模拟器上成功运行和调试本地化应用程序几天后,我发现它(或 XCode 部署过程)进入一种状态,如果模拟器设置为我支持的本地语言之一,它会崩溃在启动时使用以下堆栈:

3   CoreFoundation                      0x01780e6a +[NSException raise:format:] + 58
4   UIKit                               0x008050fa -[UINib instantiateWithOwner:options:] + 2024
5   UIKit                               0x00806ab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
6   UIKit                               0x0060c17a -[UIApplication _loadMainNibFile] + 172
7   UIKit                               0x0060ccf4 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 
8   UIKit                               0x00617617 -[UIApplication handleEvent:withNewEvent:] + 1533
9   UIKit                               0x0060fabf -[UIApplication sendEvent:] + 71
10  UIKit                               0x00614f2e _UIApplicationHandleEvent + 7576
11  GraphicsServices                    0x01e13992 PurpleEventCallback + 1550

发生崩溃是因为 UIApplication 无法加载 MainWindow.nib 文件:

由于未捕获而终止应用 例外 'NSInternalInconsistencyException', 原因:'无法在捆绑包中加载 NIB: 'NSBundle /.app> (已加载)',名称为 'MainWindow''

当您本地化应用程序时,您有几个选择。您可以执行以下一项(或两项)操作:

根据设备上的语言对每个加载的 Xib 文件进行本地化。因此,您的本地化 UI 完全是从 Interface Builder 配置的。 您可以为每个语言目标设置一个 Localizable.strings 文件,并从代码中访问其中的字符串。

我选择了后者,因为我希望将所有本地化字符串放在一个位置(因此可以一次全部翻译)。这意味着我的项目(fr.lproj、zh-Hant.lproj 等)的语言特定目录中没有任何 xib 文件。相反,我的 en.lproj 充满了我所有的 xib 文件(构建后的 nib 文件)和包含相应翻译的 Localizable.strings 文件的语言特定目录。

正如我所提到的,这已经好几天了。今天(我不确定究竟是什么时候),模拟器上的应用程序在启动时开始崩溃。在设备上安装应用程序运行良好,在模拟器上以英文模式运行应用程序运行良好。

经过大量的填充后,我意识到模拟器正在崩溃,因为它正在语言特定目录(fr.lpro、sz-Hant.lproj、ja.lproj,具体取决于语言设置)中查找其 nib 文件)。

因此,在模拟器无法在特定语言目录中找到 nib 后,它似乎处于未查看默认语言目录 (en.lproj) 的状态。

我通过进入模拟器的应用程序目录解决了这个问题(基于上面的异常消息):

/用户/.../库/应用程序 支持/iPhone Simulator/4.3/Applications//.app

然后进入特定语言的子目录并将所有 nib 文件从 en.lproj 复制到该目录中。

手动复制文件后,模拟器加载特定语言的 nib 文件(实际上只是 en.lproj 目录中文件的副本),一切正常。

所以我的问题:

这只是模拟器中的错误吗? 对此表示反对 还有其他人遇到过这个问题吗? 是的 这是由于我不小心切换了一些晦涩的 XCode 设置造成的吗? 不,看起来不像

更新

今天发现这个问题不仅限于模拟器,设备上也会出现这种情况。所以我上面描述的解决方法(将笔尖从默认语言目录复制到目标语言目录)显然不适用于手机。

我尝试了 McCygnus 的建议修复(删除我的 xib 的所有本地化,这会将它们移回根目录)并为我排序。所以我猜本地化系统会检查当前语言目录,然后是根目录,它不会回退到您的默认语言。

【问题讨论】:

我也有这个问题。它在模拟器和设备上都被复制。我只看到一个困难的解决方案 - 将相同的 .xib 文件添加到每个 .lproj 文件夹。这似乎在逻辑上不正确,但我找不到任何其他解决方案。有什么想法吗? @berec 因此,您要确保所有 xib 都在根目录中。如果它们不在特定于语言的目录中,您可以依赖它们在 en.lproj 中找到。 【参考方案1】:

我最近遇到了这个问题,当时我有一个英文版的笔尖,但没有将它本地化为任何其他语言(MyNib 在 en.lproj 中)。模拟器仅在其他语言目录(da.lproj、de.lproj 等)中查找 MyNib,如果找不到,则不会退回到英文版本。我通过删除笔尖的英文本地化来修复它。这导致它与其他资源一起位于应用程序包的根目录中,而不是在 en.lproj 中。之后,一切都完美无缺。

我对此有点困惑,因为我认为本地化系统会按照用户的首选顺序检查所有语言,而开发人员通常使用英语作为包罗万象的语言。我不确定这是加载行为的变化还是模拟器错误(我从未在设备上尝试过)。我猜是后者,但我不确定。这提醒我,我需要提交一份错误报告。

【讨论】:

+1 这听起来像同样的问题。我想我们中的一个或两个都应该记录它:)【参考方案2】:

如果你正在使用

[[Class alloc] initWithNibName:@"aNibName" bundle:nil];  

改成

[[Class alloc] initWithNibName:@"aNibName" bundle:[NSBundle mainBundle]];

【讨论】:

【参考方案3】:

我想分享相同的症状但不同的根本原因。我删除了 McCygnus 暗示的本地化(谢谢),但仍然在 iPad 上遇到了同样的异常,只是。事实证明,我的 Info.plist 文件包含指向 iPad 特定主窗口 nib 文件 (MainWindow-iPad.nib) 的链接。删除后,一切正常。

【讨论】:

【参考方案4】:

我能够通过简单地重新启动 xcode 来解决这个问题。 =/

【讨论】:

我现在很生气,我花了两个小时寻找这个问题,最后一个简单的关闭 xcode 并重新进入就可以了!吉普车! 我了解到,在遇到任何类型或奇怪的问题 5 分钟后重新启动 xcode 几乎总是值得尝试的。可悲的是它的工作频率。

以上是关于如何为本地化应用加载 XIB?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 iPhone 5 显示器加载 xib

如何为本地主机测试运行设置虚拟目录?

ViewController 不会在本地化应用程序中加载其 xib 文件每当我删除并重新安装时?

如何为 iOS 应用设置默认本地化

Xcode 5,xib 本地化导致手机黑屏

从资源包(非主)加载本地化的 xib 文件