【发布时间】:2013-08-29 05:46:45
【问题描述】:
我正在使用宏来简化返回本地化字符串,如下所示:
#define GetLocalStr(key, ...) \
[NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil], ##__VA_ARGS__]
基本上,如果您在本地化字符串文件中有一个条目,例如 "name" = "My name is %@";,则调用
GetLocalStr( @"name", @"Foo" );
将返回 NSString @"My name is Foo"
但是,当我运行它时,例如:
NSString * str = GetLocalStr( @"name", @"Foo" );
我收到“格式字符串不是字符串文字”警告。即使遵循关于此警告的其他答案的建议并将其替换为:
NSString * str = [NSString stringWithFormat:@"%@", GetLocalStr( @"name", @"Foo" )];
我仍然收到警告,此外,它有点违背了让生活更轻松的宏的意义。
如果没有将所有GetLocalStr 调用包装在#pragma 抑制器中,我该如何摆脱警告?
编辑 27/08
在运行 CRD 的答案并进行更多测试后,我似乎对错误做出了错误的假设。澄清一下:
本地化字符串文件:
"TestNoArgs" = "Hello world";
"TestArgs" = "Hello world %@";
代码:
NSString * str1 = GetLocalStr( @"TestNoArgs" ); // gives warning
NSString * str2 = GetLocalStr( @"TestArgs", @"Foo" ); // doesn't give warning
我的大部分翻译都没有任何参数,并且是那些发出警告的翻译,但直到我阅读了 CRD 的答案,我才建立联系。
我将单个宏更改为两个,如下所示:
#define GetLocalStrNoArgs(key) \
[[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil]
#define GetLocalStrArgs(key, ...) \
[NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil], ##__VA_ARGS__]
如果我分别调用每一个,则不会有任何警告。
我希望 GetLocalStr 扩展到 GetLocalStrNoArgs 或 GetLocalStrArgs 取决于是否传递了任何参数,但到目前为止我一直没有运气(宏不是我的强项:D )。
我正在使用sizeof(#__VA_ARGS__) 来确定是否传递了任何参数 - 它对参数进行字符串化,如果大小为 1,则为空(即 `\0')。也许这不是最理想的方法,但它似乎有效。
如果我将 GetLocalStr 宏重写为:
#define GetLocalStr(key,...) (sizeof(#__VA_ARGS__) == 1) ? GetLocalStrNoArgs(key) : GetLocalStrArgs(key,##__VA_ARGS__)
我可以使用它,但我仍然在使用它的任何地方都会收到警告,并且没有传递任何参数,而类似于
#define GetLocalStr( key,...) \
#if ( sizeof(#__VA_ARGS__) == 1 ) \
GetLocalStrNoArgs(key) \
#else \
GetLocalStrArgs(key,##__VA_ARGS__)
不会编译。如何让我的GetLocalStr 宏正确展开?
【问题讨论】:
-
@"name" = @"My name is %@";- 文字不可赋值,它不会编译。NSString * format = @"My name is %@"; NSString * str = GetLocalStr( format, @"Foo" ); NSLog(@"%@", str);不会引发任何警告(无论如何,我希望它只出现在GetLocalStr定义中),您可能需要修复引号并提供有关警告出现位置的更多详细信息。 -
你可以创建一个 NSString 类别来为你做这件事。
-
@A-Live
@"name" = @"My name is %@"行位于字符串本地化文件中,所以从技术上讲,它应该只是 "name" = "My name is %@" - 抱歉,如果不清楚。警告标记在NSString * str = GetLocalStr(...);行 -
@JoshCaswell 我知道有关此警告的其他问题,但我找不到任何对我有帮助的东西。如果您正在查看特定答案,我将不胜感激
-
好的,我用一行
"name" = "my name is %@";创建了Localizable.strings,你的代码仍然没有警告。
标签: ios objective-c string macros