C函数宏取NSString占位符

Chr*_*ris 1 macros objective-c ios c-preprocessor

在我的IOS-Project中,我有一个包含该函数的自定义Logger类(单例)

- (void)log:(NSString *)domain logLevel:(int)level logMessage:(NSString *)message
Run Code Online (Sandbox Code Playgroud)

通过以下预处理器宏全局可用:

#define MyLog(domain, level, message) [[MyLogger sharedInstance] log:domain logLevel:level logMessage:message]
Run Code Online (Sandbox Code Playgroud)

现在我打电话的时候:

MyLog(@"common", LL_ERROR, @"There was an error!");
Run Code Online (Sandbox Code Playgroud)

一切正常.但实际上,logMessage有时会包含字符串占位符.所以最大的问题是:如何让我的宏接受这样的调用

MyLog(@"common", LL_ERROR, @"There was an error: %@", [error debugDescription]);
Run Code Online (Sandbox Code Playgroud)

在当前的解决方案中,Xcode抱怨道:"为类似函数的宏调用提供了太多的参数".

Mar*_*n R 5

首先,您必须更改log方法以采用"可变参数列表",例如:

- (void)log:(NSString *)domain logLevel:(int)level logMessage:(NSString *)message, ...
{
    va_list argList;
    va_start(argList, message);
    NSString *fullMessage = [[NSString alloc] initWithFormat:message arguments:argList];
    va_end(argList);

    NSLog(@"domain:%@, level:%d: %@", domain, level, fullMessage);
}
Run Code Online (Sandbox Code Playgroud)

然后,您必须更改MyLog宏以使用可变数量的参数.这是一个GNU功能(http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html),它也适用于Clang:

#define MyLog(domain, level, message, ...) \
   [[MyLogger sharedInstance] log:domain logLevel:level logMessage:message, ##__VA_ARGS__]
Run Code Online (Sandbox Code Playgroud)

现在

MyLog(@"common", LL_ERROR, @"There was an error!");
MyLog(@"common", LL_ERROR, @"There was an error: %@", [error debugDescription]);
Run Code Online (Sandbox Code Playgroud)

两者都应该没有问题.