我不擅长C(我是iOS开发人员),所以这让我感到困惑:
我有一个头文件,我在其中定义了一些本地化助手:
#ifndef LocalizationMacros_h
#define LocalizationMacros_h
static NSString * forcedLanguage = nil;
static inline void forceLanguage(NSString*language){
NSLog(@"Forcing language %@ (%i)", language, &forcedLanguage);
// Output: Forcing language de (5248160)
forcedLanguage = language;
}
static inline NSString * translate(NSString * language, NSString * key){
NSLog(@"Forced language: %@ (%i)", forcedLanguage, &forcedLanguage);
// Output: Forced language: (null) (5248236)
// ... do some stuff to put translation into result ...
return result;
}
#endif
我不明白为什么forcedLanguage
的地址在forceLanguage()
和translate()
之间发生变化,导致(null)
作为其值。有人可以启发我吗?
答案 0 :(得分:4)
您正在为包含标头的每个源文件定义forcedLanguage
变量的副本。在标题更改中:
static NSString * forcedLanguage = nil;
为:
extern NSString * forcedLanguage;
然后在一个源文件(理想情况下与您的标题对应的文件)中定义:
NSString * forcedLanguage = nil;
为了将来参考,经验法则是:变量声明进入头文件,变量 definitions 进入源文件。
答案 1 :(得分:2)
static
关键字将对象本地化到放置它的翻译单元 - 您已将其放在头文件中,因此它可以包含在多个翻译单元中。
这里static
被用作连接修饰符;在这种情况下,它不是存储类说明符 - 在函数外部声明的所有数据在任何情况下都将具有静态存储类。你想要的是使它全球化(事实而不是推荐) - 即给它extern
联系。无论您是否声明extern
,外部链接都是默认值。
如果你给它外部链接,那么标题必须只包含一个声明,而不是实例化 - 实例化必须在一个翻译单元中。