iOS 预编译指令

一、简介

预编译指令在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相反!

例子、DebugRelease模式

#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).#importObjective-C导入头文件的关键字,#includeC/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代理方法

新建UITableViewController子类

六、编译器控制

使用#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中的预编译指令的初步探究

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容