Conditional compilation 处理条件语句
在日常工作中,其实宏命令最常用的情景是处理条件语句。预处理器会在编译之后调整代码,先根据类对象宏命令的值,再决定某些代码是否执行,这就提高了编译的效率。
比如说,我想建一个可以在 iPad 或者 iOS 模拟器运行的应用程序。当我在模拟器中运行它的时候,我会在 debug 模式下写一些内容,但我希望当我用真机调试的时候,这些内容不要出现。这时候我就可以用宏命令来处理,在编译前就把这些代码处理掉。注意啦,这些代码并不是被我删掉了,而是用宏命令让它们不被编译。
它的作用有一些类似于 Objective-C 中的 assert(),但是这里用到的是宏命令,并且它只在 debug 模式下运行。
处理条件语句要用到一些编译器命令,最常见的是 #ifdef, #if, #else 和 #endif。
我们从最简单的 #ifdef 和 #endif 入手,它们是把代码包裹起来,只有当宏被定义(#define)才运行。
比如在下面我创造了一个叫做 PRINT_JAMES 的宏,只有当宏被定义的时候,才会创建了对象,并且打印欢迎词:
#define PRINT_JAMES
#ifdef PRINT_JAMES
Person *person = [[Person alloc] initWithName:@"James"];
[person printGreeting];
#endif
注意我们上面没有给 PRINT_JAMES 赋值,而是仅仅表示它是存在的。
你可以在这里加上 #else,它是这些宏里唯一的被判定为真就会编译的部分。比如下面这样写的代码,就是可以编译的:
#define PRINT_JAMES
#ifdef PRINT_JAMES
Person *person = [[Person alloc] initWithName:@"James"];
[person printGreeting];
#else
THIS WILL COMPILE JUST FINE
EVEN THOUGH THERE IS THIS
TEXT HERE.
#endif
当预处理器处理这段代码的时候, #else 这部分的代码就会被移除,而当因为 PRINT_JAMES 已经被定义了。所以上面这段代码其实就是这个样子的:
Person *person = [[Person alloc] initWithName:@"James"];
[person printGreeting];
如果要进一步使用预处理器,可以用 #if 和一些运算符(==, >, 和 >=)来比较某些特殊值。你甚至可以在里面做嵌套,比如说这样:
#define DEBUG_MODE 2
#if DEBUG_MODE >= 1
NSLog(@"Entering debug mode");
#if DEBUG_MODE >= 2
NSLog(@"Verbose mode enabled");
#endif
#endif