Objective-C和Sprite Kit游戏开发从入门到精通
上QQ阅读APP看书,第一时间看更新

2.16 预处理

前面的内容中,我们已经多次看到预处理的使用,如#define、#ifndef、#endif等指令,它们以行为单位,而且结尾没有分号,这是预处理和代码最大的区别之一。

下面,我们将会对常用的预处理指令做一些总结,主要包括:

❑ #define和#undef指令。

❑ 条件编译指令。

❑ #import指令。

■2.16.1 #define和#undef指令

#define指令的功能就是定义宏,我们可以定义很简单的宏,简单到只有一个标识名称,如下面的代码。

    #define DEBUG

这样,就可以根据是否定义了这个宏来判断项目是在调试中,还是正式发布了,我们可以使用#ifdef指令判断一个宏是否已定义,而使用#ifndef指令判断一个宏是否没有定义。

使用#define指令定义的宏,可以使用#undef指令撤消,如下面的代码。

    #undef DEBUG

#define指令的另一个功能就是模拟定义常量,如下面的代码。

    #define DT_IPHONE4 4
    #define DT_IPHONE5 5
    #define DT_IPAD 1000

此外,我们还可以利用#define定义一些复杂的宏,如下面的代码。

    #define IsEvenNumber(n) (n % 2 == 0)

其中,我们定义了IsEvenNumber宏,其功能是判断一个数是否为偶数,它使用起来和函数类似,如下面的代码。

    int num = 100;
    if (IsEnenNumber(num)) {
        NSLog(@"%i是偶数", num);
    }else{
        NSLog(@"%i不是偶数", num);
    }

此外,如果一个#define指令的定义过长,我们可以将它们分行,但需要使用“\”符号放在前一行的结尾处,用以说明下一行与本行是同一指令。

■2.16.2 条件编译指令

通过定义宏,还可以指定在不同的条件下编译不同的代码,此时,我们可以使用#define定义一些与系统平台相关的标识,然后根据这些标识将软件编译成不同的版本。与条件编译相关的指令包括:

❑ #ifdef指令,判断一个宏标识是否已定义。

❑ #ifndef指令,判断一个宏标识是否没有定义。

❑ #endif指令,与#ifdef或#ifndef指令组成一个代码块。

❑ #elif和#else指令,一般与#ifdef和#endif指令组合使用,以判断不同条件下的代码执行情况。

如下面的代码,将根据不同的设备类型来编译相应的代码。

    #define IPhone
    #ifdef IPhone
        // iPhone设备代码
    #elif IPad
        // iPad设备代码
    #else
        // 其他类型设备代码
    #endif

此外,在头文件中,如前面我们定义的CApp.h文件,其中使用了一个模式化的预处理代码,我们再来看一看。

    #ifndef __CApp_h__
    #define __CApp_h__
    #endif

这三个预处理指令的功能是在代码文件中防止多次包含头文件,以提高代码的编译效率。

■2.16.3 #import指令

#import指令的功能就是引用头文件,我们已经多次使用,再次说明一下:

❑ 使用一对尖括号<>引用的头文件是系统资源,如Foundation.h文件。

❑ 使用一对双引号""引用的头文件是“外部”资源,可能是第三方框架或自定义的头文件。