【iOS】PCH预编译文件

PCH(Precompiler Header),译作“预编译头文件”。

原理:PCH,顾名思义,我们可以在程序编译的时候放置一些提前需要编译的内容。被编译的代码会放到每一个OC文件中被使用(即一处编写,编译后处处使用)。哪些代码需要放到PCH中,其实是编译时间和开发效率之间的衡量。

Xcode7以前在创建项目的时候会自动创建PCH文件,但以后的版本在创建项目的时候默认不生成PCH,但我们可以手动创建并关联程序。

创建

新建PCH文件,文件名称和工程名称保持一致(为什么要保持一致?Xcode7之前默认创建的PCH文件就是和工程名称一致的,我们可以模仿他,其实这就类似是一种规范,你也可以按照自己的规则进行命名)

创建完成后,PCH中的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// PCHDemo.pch
// PCHDemo
//
// Created by 开发 on 2020/5/10.
// Copyright © 2018 南京凌硕科技有限公司. All rights reserved.
//

#ifndef PCHDemo_pch
#define PCHDemo_pch

// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.

#endif /* PCHDemo_pch */

我们尝试加入一个描述屏幕尺寸的宏

1
2
#define UIScreenWidth [UIScreen mainScreen].bounds.size.width
#define UIScreenHeight [UIScreen mainScreen].bounds.size.height

AppDelegate中使用,编译报错了

我们把PCH文件导入当前类试下,编译运行没问题

1
2
3
4
#import "PCHDemo.pch"

NSLog(@"%f", UIScreenWidth);
// 输出:375.000000

如果我们每次用到这个文件内的代码块都需要导入到对应类文件中,这和普通头文件没什么区别啊!接下来我们看看如何正确使用它。

使用

要想使用自己创建的PCH文件,必须到工程设置中进行配置

配置完成后,我们把之前在AppDelegate中导入的头文件移除,再次编译运行

1
2
NSLog(@"%f", UIScreenWidth);
// 输出:375.000000

这时候就算配置完成了,在该项目中其他任何OC文件中都可以使用PCH中定义的代码了。

注意:填写预编译文件路径的时候前面一定不要加斜杠’/‘,否则会找不到对应的文件夹。

公有头文件

如果项目中有很多地方都用到了一个分类,此时我们就没必要每个类中都导入需要使用的分类的,可以在PCH中导入这个分类就行。

1
2
// PCHDemo.pch
#import "UIView+Layout.h"

环境变量

我们可以根据环境变量定义一些我们需要的代码

1
2
3
4
5
#ifdef DEBUG
// Debug环境
#else
// Release环境
#endif

针对OC做处理

在其他非OC文件中不能使用么?我们可以创建一个test.c文件试下,PCH文件中导入了一个分类

1
2
3
4
5
// PCHDemo.pch
#define UIScreenWidth [UIScreen mainScreen].bounds.size.width
#define UIScreenHeight [UIScreen mainScreen].bounds.size.height

#import "UIView+Layout.h"

编译报错了,为什么?因为编译的时候会把PCH中的所有代码都放到需要编译的代码文件中,由于test.c不支持OC,所以会编译报错。解决方案很简单,我们可以根据环境变量去判断哪些文件需要使用宏定义的代码。

1
2
3
4
5
6
7
8
#ifdef __OBJC__
// OC文件
#import "UIView+Layout.h"

#else
// 非OC文件

#endif

使用系统提供的环境变量__OBJC__指定只有OC文件才可以导入相关类头文件,此时非OC文件就不受PCH文件影响了,正常编译运行。