27

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

FOO=BAR

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

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

 myMethodThatTakesAnNSString(FOOLITERAL);

我希望我只是以某种方式错过了明显的东西,但我似乎找不到合适的预处理器巫毒来获得我需要的东西。

4

5 回答 5

36

使用字符串化运算符 #从符号中生成 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因为字符串化运算符不会出现在该宏的主体中。

于 2011-09-30T04:19:14.603 回答
29

这是亚当罗森菲尔德答案的修改版本,语义更清晰:

#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);
于 2013-02-04T01:09:39.497 回答
2

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

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

myMethodThatTakesAnNSString(@OS_STRINGIFY(FOO));
于 2021-04-25T06:51:54.990 回答
0

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

FOO=\@\"BAR\"

并使用代码方面,

[NSString stringWithFormat:@"macro: %@", FOO];
于 2017-08-17T11:31:16.080 回答
-2

你到底看到了什么错误?这种类型的事情确实如你所料:

#define kMyString @"MyString"

[NSString stringWithFormat:@"macro: %@", kMyString];
于 2011-09-30T04:12:44.473 回答