最近在做一个在打 log 的宏中待上每个模块的名字的任务,一个应用拆分下来有 20-30 个 framework, 不可能让每一个打log 的地方都手动改一下,加上自己打 log 的前缀, 打算重写掉之前打log 这个宏在预处理阶段就让每个打log的调用带上所属模块的名称,所以需要在预编译期间获得每个模块的名称,如果在 runtime 期间拿到,可以直接读info.plist 里面的值(如果这个模块进了主工程,读出来的值都会是一样的值),所以只能在预编译期间拿这个值。
最后在Clang找到了 __MODULE__
这个在 Clang
中像 __FILE__
一样的预定义的宏,但是有区别的是,__MODULE__
不像 __FILE__
一样,它不是字符串,我们最终需要把 __MODULE__
转成一个字符串。
__MODULE__
被定义的前提是 Xcode 的 build setting
里面 define module
要打开
如果是通过 CocoaPods 引入的源码,需要在 podspec 文件里面加入
s.pod_target_xcconfig = {'DEFINES_MODULE' => 'YES'}
最后结果:
#ifdef __MODULE__
#define stringify(arg) #arg // 将入参转换为字符串
#define preprocess1(arg) stringify(arg) // 将 __MODULE__ 一级替换为模块名字
NSString moduleName = [NSString stringWithFormat:@"%s", preprocess1(__MODULE__)]; // 将 C 字符串转换为 OC 字符串
#endif