预处理器宏值到Objective-C字符串文字

时间:2011-09-30 04:08:22

标签: objective-c cocoa cocoa-touch c-preprocessor stringification

我在构建设置中定义了预处理器宏

FOO=BAR

这个值我想按摩到可以传递给方法的Objective-C字符串文字。以下#define不起作用,但它应该展示我想要实现的目标:

 #define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR"

 myMethodThatTakesAnNSString(FOOLITERAL);

我希望我在某种程度上错过了明显的东西,但我似乎无法找到合适的预处理器伏都教来获得我需要的东西。

5 个答案:

答案 0 :(得分:35)

使用字符串化运算符 #从符号中生成一个C字符串。但是,由于预处理器的怪癖,您需要使用两个额外的宏层:

#define FOO BAR
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define FOOLITERAL @ STRINGIZE2(FOO)
// FOOLITERAL now expands to @"BAR" 

额外图层的原因是字符串化运算符只能用于宏的参数,而不能用于其他标记。其次,如果宏的参数在宏的主体中应用了字符串化运算符,则该参数扩展为另一个宏。因此,为了确保扩展FOO,我们将换行另一个宏,以便在展开STRINGIZE2时,它也会扩展FOO,因为字符串化运算符不会出现在该宏的主体中。

答案 1 :(得分:28)

这是Adam Rosenfield的答案的修改版本,其语义更清晰:

#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)

我用它代替这样的代码:

case OneEnumValue: name = @"OneEnumValue"; break;
case AnotherEnumValue: name = @"AnotherEnumValue"; break;

用这个:

#define case_for_type(type) case type: name = NSStringize(type); break

case_for_type(OneEnumValue);
case_for_type(AnotherEnumValue);

答案 2 :(得分:0)

您需要定义预处理器宏,如

FOO=\@\"BAR\"

并使用代码方面,

[NSString stringWithFormat:@"macro: %@", FOO];

答案 3 :(得分:0)

SDK 的 OS_STRINGIFY(s) 中预定义了一个方便的宏 /usr/include/os/base.h,它包含在 Foundation.framework 中。

因此您可以使用以下代码而无需额外定义。

myMethodThatTakesAnNSString(@OS_STRINGIFY(FOO));

答案 4 :(得分:-2)

你到底看到了什么错误?这种类型的东西确实按预期工作:

#define kMyString @"MyString"

[NSString stringWithFormat:@"macro: %@", kMyString];