如何在objective-C中使用可变方法定义宏?

时间:2014-02-02 15:30:44

标签: ios objective-c macros variadic

我试图调用的方法是

- (void)addLogWithLevel:(MDCLogLevel)logLevel logContent:(NSString *)logContent, ...
{
    va_list args;
    va_start(args, logContent);
    NSString *message = [[NSString alloc] initWithFormat:logContent
                                               arguments:args];
    va_end(args);
    MDCLog *log = [MDCLog logWithContent:message content:logLevel];
    [self.deviceLogs addObject:log];
}

我已将宏定义为;

#define MDCLogDebug(format, ...) [[MDCLogController sharedController] addLogWithLevel:MDCLogLevelDebug logContent:(__VA_ARGS__)];

我尝试过这种宏的各种格式,但似乎没什么用。

如果我要打电话;

MDCLogDebug(@"Test:%@", @"Hey");

我在控制台中看到的只是;

  

我哪里错了?我是使用Variadic方法的新手,我的C不是那么棒!

1 个答案:

答案 0 :(得分:10)

实际上,你的问题并不直接与Objective-C有关,而是与C本身有关,因为宏是普通的C预处理器指令。

在宏中,__VA_ARGS__表示放置的参数而不是...

因此,在致电MDCLogDebug(@"Test:%@", @"Hey")时,format参数为@"Test:%@"__VA_ARGS__代表其后的其余参数,即您@"Hey"中的@"Test:%@"情况下。

如果您想将@"Hey"logContent:作为参数传递给#define MDCLogDebug(format, ...) [[MDCLogController sharedController] addLogWithLevel:MDCLogLevelDebug logContent:format, __VA_ARGS__] ,则必须明确告知,使用:

##

注意:更好的解决方案是在__VA_ARGS__之前使用__VA_ARGS__前缀,这样如果format为空,则不会添加逗号(即如果你只传递MDCLogDebug(@"Foo")参数但之后没有任何内容,例如#define MDCLogDebug(format, ...) [[MDCLogController sharedController] \ addLogWithLevel:MDCLogLevelDebug \ logContent:format, ## __VA_ARGS__] ):

{{1}}

(注意:我在上面的最后一个宏定义中使用了反斜杠,允许将宏写在多行上,而不是将其写在一个大的长行上)

有关详细信息,请see the official GCC documentation about Variadic Macros here