闻道丶iOS(大杂烩)Build-UpiOS开发

iOS开发中的头文件引用

2017-03-07  本文已影响1005人  Mr_GaoYu

头文件引用一般都会随着项目规模变大而可读性变差。当大部分精力花费在业务上往往容易忽视头文件的使用和规范。整理下常见的头文件疑问和知识点,希望能给正在寻找这方面答案的人一些帮助。

一、基本头文件引用方式

说到OC中的头文件引用,不得不说三个基本的引用方式(#include、#import、@class) 和 预编译头文件(.pch)。

#include:

#import:

如果想深究,import的实现是通过#ifndef一个标志进行判断,然后在引入后#define这个标志,来避免重复引用的。

想象一下它长这样:

  #ifndef MyFile_h

  #define MyFile_h

  // Some code

  #endif

@class:

.pch预编译头文件:

import的实质还是拷贝粘贴,这样就带来两个问题:

为了解决这些问题,C系语言引入了预编译头文件(PreCompiled Header),将公用的头文件放入预编译头文件中预先进行编译,然后在真正编译工程时再将预先编译好的产物加入到所有待编译的Source中去,来加快编译速度。比如iOS开发中Supporting Files组内的.pch文件就是一个预编译头文件,默认情况下,它引用了UIKit和Foundation两个头文件--这是在iOS开发中基本每个实现文件都会用到的东西。

当然预编译头文件也不应该乱用误用,否则将导致工程中随处可用本不该能访问的代码。编译器无法给出准确的问题报错,增加了编译出错的可能性。

预编译头文件的使用标准:
// include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// 包含系统基础库文件 或者 项目中经常使用到但不经常修改的特定头文件

二、OC中的Modules和它的头文件引用

Modules相当于将框架进行了封装,然后加入在实际编译之时加入了一个用来存放已编译添加过的Modules列表。如果在编译的文件中引用到某个Modules的话,将首先在这个列表内查找,找到的话说明已经被加载过则直接使用已有的,如果没有找到,则把引用的头文件编译后加入到这个表中。这样被引用到的Modules只会被编译一次,但是在开发时又不会被意外使用到,从而同时解决了编译时间和引用泛滥两方面的问题。

我们看看.moudulemap的定义:

  framework module LDPMChart {
       umbrella header "LDPMChart-umbrella.h"
       export *
       module * { export * }
  }

这个Module定义了首要头文件(LDPMChart-umbrella.h),需要导出的子modules(所有),以及需要link的框架名称(LDPMChart)。需要指出的是,现在Module还不支持第三方的框架,所以只有SDK内置的框架能够从这个特性中受益。另外,在C++的源代码中,Modules也是被禁用的。

@import:

大部分情况下等价于
#import <LDPMChart/LDPMChart.h>。
但后者需要增加一条使用限制:在Build Settings中将Enable Modules(C and Objective-C)打开。
这样就可以保持旧的写法,避免把项目中的所有引用都进行手动修改。不过,后者的引用方式在语法检查时并不严格,在缺少modulemap头文件暴露支持时,可以编译通过但会有missing submodule的warning。如果方便还是建议使用新的引用方式@import 规范化引用。

三、小问题附录

#import "" vs #import <>

Header Search Path

上一篇 下一篇

猜你喜欢

热点阅读