有没有办法在不重新启动应用程序的情况下使 NSBundle 本地化缓存失效? [iOS]

Posted

技术标签:

【中文标题】有没有办法在不重新启动应用程序的情况下使 NSBundle 本地化缓存失效? [iOS]【英文标题】:Is there a way to invalidate NSBundle localization cache, withour restarting application? [iOS] 【发布时间】:2012-11-11 14:48:19 【问题描述】:

假设我们可以在运行时更改 Localizable.strings,即放置在 NSBundle 中 目前,即使我们改变它的内容,NSLocalizedString 也会返回旧的(缓存的)值。

    运行应用程序 获取特定 key1 的 LocalizableString 更改 Localizable.strings key1 = value2 检查特定 key1 的 LocalizableString 是否 == value2

我已经尝试过的:

[[NSBundble mainBundle] invalidateResourceCache] [UIApplication_performMemoryWarning] 试着看看,如果有一些字典。用于缓存,在 NSBundle 的 ivars 中。 试图在 NSBundle 的 GNUStep 实现中看到,但它与我们在 ios 6.0 中的不同

我不能做什么(根据定义): - 我无法调配 [NSBundle localizableStringForKey:value:table] - 我无法更改宏 - 一般来说,我不能影响任何原始项目代码,只能在第 4 步添加一些内容

这仅用于开发目的。所以,我不需要在AppStore什么的发布它,所以任何私有的方法,或者解决方案都可以。

所以,问题是。可能有人知道如何做到这一点,或者有人给我另一个想法如何做到这一点?谢谢。

【问题讨论】:

"假设我们可以在运行时 Localizable.strings 中进行更改" - 你不能。 好吧,我可以在模拟器上运行应用程序时做到这一点。 在模拟器上,应用程序在您的用户帐户的权限下运行,它们不限于在沙箱中运行。在设备上,您无法修改位于 app bundle 中的文件。 【参考方案1】:

您可以使用 uncache 解决方案。

在您的 lproj 文件夹中使用 Localizable.nocache.strings

例如example.bundle/Resources/de.lproj/Localizable.nocache.strings

通过 FileManager 获取url 后加载本地化字符串。

func localizedString(key: String) -> String 
   let bundle = Bundle(url: bundleUrl)
   return bundle.localizedString(forKey: key, value: nil, table: "Localizable.nocache")

【讨论】:

【参考方案2】:

注意:此解决方案使用私有 API,如果您使用此代码,您向 App Store 提交的应用将被拒绝。

所以,经过一番搜索,我找到了对我有帮助的链接

How to remove NSBundle cache

// First, we declare the function. Making it weak-linked 
// ensures the preference pane won't crash if the function 
// is removed from in a future version of Mac OS X.
extern void _CFBundleFlushBundleCaches(CFBundleRef bundle) 
  __attribute__((weak_import));

BOOL FlushBundleCache(NSBundle *prefBundle) 
    // Before calling the function, we need to check if it exists
    // since it was weak-linked.
    if (_CFBundleFlushBundleCaches != NULL) 
        NSLog(@"Flushing bundle cache with _CFBundleFlushBundleCaches");
        CFBundleRef cfBundle =
           CFBundleCreate(nil, (CFURLRef)[prefBundle bundleURL]);
        _CFBundleFlushBundleCaches(cfBundle);
        CFRelease(cfBundle);
        return YES; // Success
    
    return NO; // Not available

刷新包缓存后,使用新的本地化键。 所以现在我不需要在模拟器中重新启动我的应用程序来查看可本地化字符串的变化。

【讨论】:

由于这是私有 API 使用,您将无法使用此解决方法提交应用程序。我刚刚尝试过,但失败了。 正如问题本身所提到的:这仅用于开发目的。所以,我不需要在 AppStore 什么的发布它,所以任何私有的方法,或解决方案都可以。

以上是关于有没有办法在不重新启动应用程序的情况下使 NSBundle 本地化缓存失效? [iOS]的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在不使用子项的情况下使 Firebase 搜索查询不区分大小写? [复制]

是否可以在不重新编译的情况下使科尔多瓦应用程序可调试?

有没有办法在不重新启动 Xcode 6 的情况下打开 Swift Playground?

如何在不先启动 IE 的情况下使我的 WinCE 应用程序中的网络工作?

有没有办法在不重新启动 Solr 服务器的情况下动态更新同义词文件?

有没有办法在不重新启动终端的情况下通过 bash_profile “资源”? [复制]