我在构建设置中定义了预处理器宏
FOO=BAR
这个值我想按摩到可以传递给方法的Objective-C字符串文字。以下#define不起作用,但它应该展示我想要实现的目标:
#define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR"
myMethodThatTakesAnNSString(FOOLITERAL);
我希望我在某种程度上错过了明显的东西,但我似乎无法找到合适的预处理器伏都教来获得我需要的东西。
答案 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];