一、简介
预编译指令在iOS 中的主要功能:
1、宏定义
2、条件编译
3、文件包含
4、错误、警告处理
5、编译器控制
二、宏定义
例子:宏定义常量和const
定义常量的区别
宏定义:预编译阶段(编译之前)进行字符串替换,不检查数据类型和分配内存,宏可以定义方法和函数。
const
:编译阶段进行类型检查和分配内存。
不同:
处理时刻:宏定义是预编译阶段(编译之前)进行字符串替换,const
定义常量是在编译阶段进行类型检查和分配内存
类型检查:宏定义不做类型检查,const
定义常量编译时会做类型检查和分配内存
分配内存:宏定义不分配内存,const
定义常量有分配内存
宏定义的优点:宏可以定义方法和函数,const
不行
宏定义的缺点:使用太多的宏将使预编译时间变长,每次都要重新替换
宏定义要注意添加括号,如果没有添加括号可能会影响计算结果
例如,宏定义#define SUM(A, B) A+ B
求 2 * SUM(3, 4) *5 的计算结果
期望:2 * 7 * 5 = 70
实际:2 * 3 + 4 * 5= 26
所以应该加上括号:#define SUM(A, B) (A + B)
2 * (3 + 4) * 5 = 70
三、条件编译:#if , #ifdef , #ifndef
的使用
1、#if
#if condition(表达式1)
//程序段1
(#elif condition(表达式n)
//程序段n
)
...
(#else
//程序段3
)
#endif
说明 : 如果 表达式1(condition : true
),则执行 程序段1,(否则如果 表达式2(condition : true
),则执行 程序段n),(否则执行 程序段3).
2、#ifdef
#ifdef macro(标识符1)
//程序段1
(#else
//程序段2
)
#endif
说明 : 如果 有定义标识符1(#define macro
),则执行 程序段1,(否则执行 程序段2).
3、#ifndef
#ifndef macro(标识符1)
//程序段1
(#else
//程序段2
)
#endif
说明 : 如果 没有定义标识符1(#define macro
),则执行 程序段1,(否则执行 程序段2).与#ifdef
相反!
例子、Debug
和Release
模式
#ifdef DEBUG
// 测试环境
#else
// 正式环境
#endif
具体应用:自定义日志输出格式
#ifdef DEBUG
#define YDLog( s, ... ) NSLog( @"< %@:(%d) > %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define YDLog( s, ... )
#endif
例子、判断真机或者模拟器环境
#if TARGET_OS_IPHONE // 判断是真机
// 真机环境
#elif TARGET_IPHONE_SIMULATOR // 判断是模拟器
// 模拟器环境
#endif
当我们新建一个头文件(.h)或者预编译文件(.pch),文件会自带以下内容
#ifndef Header_h
#define Header_h
#endif /* Header_h */
这段预编译指令是为了防止该文件被重复引用的问题
四、文件包含:#import、#include、@class
的区别
1).#import
是Objective-C
导入头文件的关键字,#include
是C/C++
导入头文件的关键字,使用#import
头文件会自动只导入一次,不会重复导入。
2).@class
告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含。
3). #import <>
用来包含系统的头文件,#import ""
用来包含用户头文件。
五、错误、警告处理
1、#error
#error
用来当你开发某个库时,需要限制某个文件需要在特殊的条件才能使用的时候非常方便
#if __has_feature(objc_arc)
#error This file must be compiled without ARC. Specify the -fno-objc-arc flag to this file.
#endif
提示这个文件只能在非ARC的环境下使用,否则编译失败
2、#warning
#warning
使用起来比较简单,在你需要注意的地方标记#warning
,后面加上警告的信息就OK
了
例如,当我们创建UITableViewController子类时,实现文件就会自动生成带警告的UITableViewDataSource
代理方法
六、编译器控制
使用#pragma mark -
让代码看起来更规范清晰
#pragma mark - Life Cycle
#pragma mark - Action
#pragma mark - Private
#pragma mark - Public
#pragma mark - Protocal
#pragma mark - Getter & Setter
方法导航生成索引
参考文章:
iOS 小知识 - #if , #ifdef , #ifndef
预编译指令#if #ifdef #elif #else #endif #import #define的简单使用
iOS中的预编译指令的初步探究
网友评论