在我的工作场所,我们的应用通过使用与下面类似的代码来确定用户会话的区域设置(尽管在启动时在到达此处之前,它会经过各种代码层,因此问题是/可能不是)通过运行以下代码可以明显看出)

#include <CoreFoundation/CoreFoundation.h>
#include <iostream>
#include <string>
#include <vector>
#include <memory>

  // Reference release
    struct reference_close
    {
        void operator()(const void *ref) const
        {
            CFRelease(static_cast<CFTypeRef>(ref));
        }
    }; // end of reference_close structure

    typedef std::unique_ptr<const void, reference_close>  reference_uptr;

    std::string get_user_locale()
    {
        reference_uptr  ref_ptr(CFLocaleCopyCurrent());
        CFLocaleRef    locale_ref(static_cast<CFLocaleRef>(ref_ptr.get()));
        if (locale_ref == nullptr)
        {
            return std::string();
        }
        const size_t      default_size(128);
        std::vector<char>  buff(default_size);
        CFStringRef        str_ref(CFLocaleGetIdentifier(locale_ref));

      if (str_ref != nullptr)
        {
            CFIndex  len(CFStringGetLength(str_ref) + 1);
            if (len > boost::numeric_cast<CFIndex>(default_size))
            {
                buff.resize(len);
            }

            buff[0] = 0;
            if (!CFStringGetCString(str_ref, &buff[0], len, kCFStringEncodingISOLatin1))
            {
                return std::string();
            }
        }

        return std::string(&buff[0]);
    } // end of get_user_locale()

int main()
{
    std::cout << "get_user_locale() : "<<get_user_locale() << std::endl;

    return 0;
}


该应用具有定义明确的捆绑包结构,其中包含必要的资源和本地化资源目录,例如Contents/Resources/ja.lproj

最近,我们面临的问题是我们必须执行以下操作

1)在偏好设置中更改系统语言和国家/地区,例如从en_US更改为ja_JP

2)重新启动机器

3)启动应用程序并查看错误输出,例如en_JP

4)重新启动应用程序以获取正确的答案,例如ja_JP

我已阅读CFLocaleCopyCurrent的文档,其中指出:


  您从该语言环境获得的设置不会更改为用户的
  偏好设置已更改,以便您的操作保持一致。
  通常,您对返回的对象执行一些操作,然后
  释放它。由于返回的对象可能会被缓存,因此您不需要
  无限期地坚持下去。


我还查看了lifetime of CFLocale上的另一个文档,该文档指出:


  从CFLocaleCopyCurrent取回的对象在以下情况下不会更改
  用户更改其首选项设置。而且,对象
  本身可能会被运行时系统缓存,因此连续调用
  CFLocaleCopyCurrent可能会返回相同的对象,即使用户具有
  更改了偏好设置。如果要确保您的语言环境
  设置与用户首选项一致,则必须同步
  首选项,并使用CFLocaleCopyCurrent获取一个新的语言环境对象。


鉴于此信息,我尝试将CFPreferencesSynchronize和/或CFPreferencesSynchronize合并到应用程序代码中(就在我调用CFLocaleCopyCurrent之前),以获取最新的语言环境。但是没有运气。

我是否需要做任何其他事情以确保从系统偏好设置中获取语言环境对象的最新/更新值?

最佳答案

使用[NSLocale autoupdatingCurrentLocale]随用户更改其语言环境设置而改变,但是NSLocale是Objective-C类,因此您需要将粘合代码实现为Objective-C ++。

这是一些未经测试的示例代码,可以帮助您:

创建一个名为AppleLocale.mm的文件(除非您的项目当然仅适用于Apple平台,所以不需要Apple名称前缀)。

#include <Foundation/Foundation.h>

std::string get_user_locale()
{
    NSLocale* locale = [NSLocale autoupdatingCurrentLocale];
    return std::string([[locale localeIdentifier] UTF8String]);
}


注意:当然,您还需要一些标头中的函数原型。

关于c++ - CFLocaleCopy当前过时的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58713505/

10-13 03:21