我正在尝试做一些非常简单的事情:一个接受字符串并将其打印到NSLog的宏。
像这样:
#define PRINTTHIS(text) \
NSLog(@"text");
但是,当我尝试将字符串传递给这个人时,我最终会将“文本”打印到控制台。是不是所有变量都替换在宏内的字符串级别?怎么做对了?
答案 0 :(得分:13)
您需要使用预处理器的'stringizing'运算符#
,可能还需要使用'token pasting'运算符'##':
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
#define PRINTTHIS(text) \
NSLog(PASTE( @, STRINGIFY(text)));
我不确定Objective-C是否要求'@'在它和开头引号之间没有空格 - 如果允许空格,则删除PASTE()操作。
请注意,您需要STRINGIFY()
和PASTE()
的高位2级间接才能正常使用宏参数。除非你做一些非常不寻常的事情(你不希望扩展宏参数),否则它几乎不会受到伤害,因此以这种方式使用这些运算符是非常标准的。
答案 1 :(得分:9)
这是编写宏的一种方法,它将其参数文本化地粘贴到一个字符串对象中,尽管它让我感到有点粗糙:
#define PRINTTHIS(text) NSLog((NSString *)CFSTR(#text))
它使用字符串化运算符将参数转换为C字符串,然后使用该字符串创建一个CFString,它与NSString一起免费桥接。
答案 2 :(得分:7)
看起来这样也行。
#define PRINTTHIS(text) NSLog(@#text);
刚试过它,似乎工作得很好。
答案 3 :(得分:4)
使用
#define PRINTTHIS(text) \
do { NSLog(@"%s", #text); } while(0)
这样,文字可以包含%字符,它的'if-proof',半冒号都在正确的位置等等......
然而,就个人而言,我认为直接使用NSLog()会更有意义。
答案 4 :(得分:3)
我认为你遇到的问题是“text”在预处理器中看起来像是一个字符串文字(引号,可能是@符号),所以它不会被替换。只是一个猜测,但这会有效吗?
#define PRINTTHIS(text) \
NSLog(@"%@", text);
PRINTTHIS(@"string");
您还可以定义一个采用C字符串而不是ObjC字符串的版本:
#define PRINTTHIS_C(text) \
NSLog(@"%s", text);
PRINTTHIS_C("string");
答案 5 :(得分:1)
我的印象是这就是你的意思,并希望
你想要一个可以带参数的字符串,同时包含其他字符串,类似于stringwithformat函数。
#define ThisMacro(value) @"Hello my name is %@, and I'm a developer", value
然后要使用宏,只需将它添加到完整字符串
的值传递给它NSLog(ThisMacro(@"Mthokozisi"))
最终结果为@"Hello my name is Mthokozisi, and I'm a developer"
答案 6 :(得分:0)
带上一粒盐...我不是Objective-C开发人员。但是在类似C函数的宏中,出现在字符串文字中的宏参数不会被它们对应的实际参数替换,所以你试图做的替换将不起作用。
这可能有效:
#define PRINTTHIS(text) \
NSLog(@text);
PRINTTHIS("your message here");
(所以引号被移出宏定义。)
Chuck在评论中指出,在Objective-C中,@被认为是令牌的一部分 在这个结构中。因此可能需要使用令牌粘贴操作符##:
#define PRINTTHIS(text) \
NSLog(@##text);
答案 7 :(得分:0)
我认为只是小心空间。这应该可以正常工作:
#define PRINTTEXT( msg ) NSLog( (msg) )
另一个例子:
#define TFCheckPoint( msg ) [TestFlight passCheckpoint: (msg) ];