宏说明
__func__打印当前函数或方法,c字符串
__LINE__打印当前行号,整数
__FILE__打印当前文件路径,c字符串
__PRETTY_FUNCTION__打印当前函数或方法(在C++中会包含参数类型),c字符串
__VA_ARGS__:可变参数宏,将"##"放在","和参数之间,那么如果参数留空的话,那么"##"前面的","就会删掉,从而防止编译错误。
"…"指可变参数。这类宏在被调用时,它被表示成零个或多个符号,包括里面的逗号,一直到到右括弧结束为止。当被调用时,在宏体中,那些符号序列集合将代替里面的__VA_ARGS__标识符。即...被替换__VA_ARGS__
#:宏中的#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号。
##:##的功能,它可以拼接符号(Token-pasting operator)。#define paster( n ) printf( "token"#n" = %d\n", token##n );paster(9)宏展开后token##n直接合并变成了token9。整个语句变成了
printf( "token9" = %d", token9 );
例子:
OC调试的两个宏:
#ifdef DEBUG
#define QLLogDebug(fmt, ...) NSLog((@"%s" fmt), __FUNCTION__, ##__VA_ARGS__);
#define QLLogError(fmt, ...) NSLog((@"ERROR%s:%d" fmt), __FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define QLLogDebug(...);
#define QLLogError(...);
#endif
#define QLAllert(condition, fmt, ...) NSAssert(condition, (@"---- assert log ---- FilePath : %s function : %s lineNum : %d" fmt), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
(@"ERROR%s:%d" fmt)只是做字符串的拼接,可以将括号去掉,但最好保留,condition是第一个参数,fmt是第二个参数的一部分,...标识可变参数
PS:在C语言中字符串中的二个相连的双引号会被自动忽略,于是"token""9""等同于"token9",这就解释了(@"ERROR%s:%d" fmt)