CFLocaleCopy当前过时的值 [英] CFLocaleCopyCurrent stale value

查看:344
本文介绍了CFLocaleCopy当前过时的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

At my workplace, our app determines the locale of the user session by using a code that is similar to below (though there are various layers of code it passes through before it reaches here at the time of startup, so the problem is/may not evident by running the code below)

#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

The app has a well defined bundle structure with necessary resources and localization resource directories e.g Contents/Resources/ja.lproj

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

Lately, we are facing an issue wherein we do the following

1)在首选项中更改系统语言和国家/地区,例如从en_US更改为ja_JP

1) Change the system language and country in the preferences e.g. change from en_US to ja_JP

2)重新启动计算机

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

3) Launch the app and see the erroneous output e.g en_JP

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

4) Re-launch the app to get the correct answer as ja_JP

我已阅读 CFLocaleCopyCurrent 的文档,该文档指出

I have read the documentation of CFLocaleCopyCurrent which states that

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

Settings you get from this locale do not change as a user's preferences are changed so that your operations are consistent. Typically you perform some operations on the returned object and then release it. Since the returned object may be cached, you do not need to hold on to it indefinitely.

我还检查了

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

The object you get back from CFLocaleCopyCurrent does not change when the user changes their Preferences settings. Moreover, the object itself may be cached by the runtime system, so successive calls of CFLocaleCopyCurrent may return the same object, even if a user has changed preference settings. If you want to ensure that your locale settings are consistent with user preferences, you must synchronize preferences and get a new locale object with CFLocaleCopyCurrent.

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

Given this info, I tried to incorporate CFPreferencesSynchronize and/or CFPreferencesSynchronize in the app code (just before I call the CFLocaleCopyCurrent) to get the most updated locale. But no luck.

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

Do I need to do anything extra to make sure that I get the most recent/updated value of locale object from the system preferences ?

推荐答案

使用

Use [NSLocale autoupdatingCurrentLocale] which will change as the user changes their locale settings, but as NSLocale is an Objective-C class you will need to implement glue code as Objective-C++.

这是一些未经测试的示例代码,为您提供了一个主意:

Here is some untested example code, giving you the idea:

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

Create a file called AppleLocale.mm (unless of course your project is for Apple platforms only so doesn't need the Apple name prefix).

#include <Foundation/Foundation.h>

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

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

Note: You'll need a function prototype in some header as well, of course.

这篇关于CFLocaleCopy当前过时的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆