iOS_预编译(宏)#if #ifdef #ifndef #elif #else #endif

2022-07-20 14:58:39 浏览数 (1)

iOS_预编译

1、预处理

ANSI C标准(是美国国家标准协会(ANSI)对C语言)规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编译效率。这些预处理命令时有ANSI C统一规定的,但它不是C语言本身的组成部分,不能直接对它们进行编译,需要在编译之前对这些特殊指令进行处理,这个过程即“预处理”。经过预处理后程序可由编译程序对预处理后的源程序进行通常的编译,得到可供执行的目标代码。

OC中的预编译指令分为三种:宏定义、条件编译、文件包含。

1、宏定义

1.1、定义 和 取消定义

  • #define 标识符 字符串:定义个宏,标识符就是这个宏的名称,一般习惯用大写字母,以便与变量名区别。只做字符替换,不分配内存空间,不做正确性检查和运算逻辑处理。
  • #undef 标识符:取消一个宏,之后这个宏的定义就无效了。但可以重新使用#define进行定义。

例如:

代码语言:javascript复制
// 不含参数
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
// 含参数
#define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c))

1.2、可变参数

参数个数可变:使用参数使用...,在需要传递参数的地方使用__VA_ARGS__

代码语言:javascript复制
// 参数个数可变
#define safeCallback(callback, ...) if (callback) { callback(__VA_ARGS__); }

1.3、宏定义中换行

需要在每行的结尾加反斜杠:

代码语言:javascript复制
#define safeCallback(callback, ...)
    if (callback) {
        callback(__VA_ARGS__);
    }

2、条件编译

根据预处理指令判断条件编译对应的代码,未满足条件的代码不会被编译(相当于没这段代码)。

条件编译指令:

  • #if 当条件为真,则编译这段代码
  • #ifdef(if define) 当宏被定义,则编译这段代码
  • #ifndef(if no define) 当宏未被定义,则编译这段代码
  • #elif(else-if) 若前面条件不满足,则执行#elif条件判断
  • #else 若前面条件不满足,则编译这段代码
  • #endif 条件编译指令结束标志

例如:

代码语言:javascript复制
#ifdef VERSIOIN_2
// 版本2代码
#elif VERSIOIN_1
// 版本1代码
#else
// 旧代码
#endif

还有一种在pch文件中可以自带一个条件编译:防止该文件的重复引用

代码语言:javascript复制
#ifndef Header_h
#define Header_h

#endif

iOS系统常用的宏:

代码语言:javascript复制
// 判断是否为真机
#if TARGET_OS_IPHONE
#endif

// 判断是否是模拟器
#if TARGET_OS_SIMULATOR // 同上。"TARGET_IPHONE_SIMULATOR"已经废弃
#endif

// 判断手机系统版本
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0
#endif


// 规定只能在ios系统下运行
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 
    // 规定运行支持的最小版本
    #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
    #endif
#endif

可以参照Availability.h文件 (路径:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/Availability.h

3、文件包含

  • C语言一般使用#include,需要注意不要重复引用
  • OC语言一般使用#import。大部分功能和#inculde一样,不过处理了重复引用的问题。
  • OC语言还有个引用声明@class,用于声明一个字符串,告诉编译器这是一个类,而这个类的实现暂时不用知道。但在实际需要用到这个类的接口时,还是需要使用#import引入。

参考: iOS 预编译指令#if #ifdef #elif #else #endif #import #define的简单使用

0 人点赞