I have a preprocessor macro defined in build settings
我在构建设置中定义了预处理器宏
FOO=BAR
That value I want to massage into an Objective-C string literal that can be passed to a method. The following #define does not work, but it should demonstrate what I am trying to achieve:
这个值我想按摩到可以传递给方法的Objective-C字符串文字。以下#define不起作用,但它应该展示我想要实现的目标:
#define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR"
myMethodThatTakesAnNSString(FOOLITERAL);
I expect that I am just missing the obvious somehow, but I cannot seem to find the right preprocessor voodoo to get what I need.
我希望我只是在某种程度上错过了显而易见的东西,但我似乎无法找到合适的预处理器伏都教来获得我需要的东西。
4 个解决方案
#1
33
Use the stringizing operator #
to make a C string out of the symbol. However, due to a quirk of the preprocessor, you need to use two extra layers of macros:
使用字符串化运算符#从符号中生成一个C字符串。但是,由于预处理器的怪癖,您需要使用两个额外的宏层:
#define FOO BAR
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define FOOLITERAL @ STRINGIZE2(FOO)
// FOOLITERAL now expands to @"BAR"
The reason for the extra layers is that the stringizing operator can only be used on the arguments of the macro, not on other tokens. Secondly, if an argument of a macro has the stringizing operator applied to it in the body of the macro, then that argument is not expanded as another macro. So, to ensure that FOO
gets expanded, we wrap in another macro, so that when STRINGIZE2
gets expanded, it also expands FOO
because the stringizing operator does not appear in that macro's body.
额外图层的原因是字符串化运算符只能用于宏的参数,而不能用于其他标记。其次,如果宏的参数在宏的主体中应用了字符串化运算符,则该参数不会扩展为另一个宏。因此,为了确保扩展FOO,我们将换行另一个宏,这样当STRINGIZE2扩展时,它也会扩展FOO,因为字符串化操作符不会出现在该宏的主体中。
#2
27
Here's a modified version of Adam Rosenfield's answer with clearer semantics:
这是Adam Rosenfield的答案的修改版本,具有更清晰的语义:
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
I use it to replace code like this:
我用它来代替这样的代码:
case OneEnumValue: name = @"OneEnumValue"; break;
case AnotherEnumValue: name = @"AnotherEnumValue"; break;
with this:
有了这个:
#define case_for_type(type) case type: name = NSStringize(type); break
case_for_type(OneEnumValue);
case_for_type(AnotherEnumValue);
#3
1
You need to define preprocessor macro like,
您需要定义预处理器宏,如,
FOO=\@\"BAR\"
And use code side like,
并使用代码方面,
[NSString stringWithFormat:@"macro: %@", FOO];
#4
-1
What error are you seeing exactly? This type of thing does work as you expect:
你到底看到了什么错误?这种类型的东西确实按预期工作:
#define kMyString @"MyString"
[NSString stringWithFormat:@"macro: %@", kMyString];
#1
33
Use the stringizing operator #
to make a C string out of the symbol. However, due to a quirk of the preprocessor, you need to use two extra layers of macros:
使用字符串化运算符#从符号中生成一个C字符串。但是,由于预处理器的怪癖,您需要使用两个额外的宏层:
#define FOO BAR
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define FOOLITERAL @ STRINGIZE2(FOO)
// FOOLITERAL now expands to @"BAR"
The reason for the extra layers is that the stringizing operator can only be used on the arguments of the macro, not on other tokens. Secondly, if an argument of a macro has the stringizing operator applied to it in the body of the macro, then that argument is not expanded as another macro. So, to ensure that FOO
gets expanded, we wrap in another macro, so that when STRINGIZE2
gets expanded, it also expands FOO
because the stringizing operator does not appear in that macro's body.
额外图层的原因是字符串化运算符只能用于宏的参数,而不能用于其他标记。其次,如果宏的参数在宏的主体中应用了字符串化运算符,则该参数不会扩展为另一个宏。因此,为了确保扩展FOO,我们将换行另一个宏,这样当STRINGIZE2扩展时,它也会扩展FOO,因为字符串化操作符不会出现在该宏的主体中。
#2
27
Here's a modified version of Adam Rosenfield's answer with clearer semantics:
这是Adam Rosenfield的答案的修改版本,具有更清晰的语义:
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
I use it to replace code like this:
我用它来代替这样的代码:
case OneEnumValue: name = @"OneEnumValue"; break;
case AnotherEnumValue: name = @"AnotherEnumValue"; break;
with this:
有了这个:
#define case_for_type(type) case type: name = NSStringize(type); break
case_for_type(OneEnumValue);
case_for_type(AnotherEnumValue);
#3
1
You need to define preprocessor macro like,
您需要定义预处理器宏,如,
FOO=\@\"BAR\"
And use code side like,
并使用代码方面,
[NSString stringWithFormat:@"macro: %@", FOO];
#4
-1
What error are you seeing exactly? This type of thing does work as you expect:
你到底看到了什么错误?这种类型的东西确实按预期工作:
#define kMyString @"MyString"
[NSString stringWithFormat:@"macro: %@", kMyString];