[译] 为什么 #import 顺序对依赖管理很重要

在 Objective-C 中,围绕 #import 顺序存在一些微妙的问题。你可能不相信我,直到你尝试在新项目中重复使用旧代码。

狂野的 #import! 一文中,我们探讨了 #import 指令过多带来的问题。但导入的太少也有可能导致头文件不好,特别是如果你没有注意 .m 文件中的 #import 顺序。

使导入最少化和完整化

在导入时,头文件应满足这两个条件:

  • 应尽量少
  • 应尽量完整

"最少 "仅表示头文件导入的内容不应超过其需要。
"完整 "是指头文件导入编译所需的所有内容。考虑一下:

#import "foo.h"
#import "bar.h"

如果删除 foo.h(或改变顺序)导致 bar.h 无法编译,那么 bar.h 并不完整。

发现不完整的 Header

依赖预编译头文件是导致头文件不完整的一种情况。特别是,预编译的头文件包含某个特定的头文件,并不意味着你可以在其他地方省略它。

另一种头文件不完整的情况是 #import 顺序不当,掩盖了依赖关系。在基于 C 的语言中,程序员在开始编写实现文件时,通常会在最大范围内包含最通用的头文件。然后依次向下,直到包含最具体的头文件:

  • 1、系统头文件
  • 2、其他头文件
  • 3、最后,该文件自身的头文件

这是一种倒退。考虑一下依赖于 <QuartzCore/QuartzCore.h> 的头文件 foo.h。如果 foo.m 首先导入 QuartzCore,然后导入其他内容,最后才导入自己的头文件,那么你可能就不会觉得有必要在 foo.h 中导入 QuartzCore 了。......而下一个程序员如果直接导入 foo.h,就会导致程序崩溃。

原作者在评论答疑中对于此处的解释:
#import is a preprocessor directive. It’s effectively the same as copying and pasting. So if you import QuartzCore first, and your “self” header last, it all expands in your .m before it’s compiled. That’s why the ordering matters.

But if it’s expanded before other headers that use it, those headers will pick it up by accident, not by design. By importing it at the end, any headers that need it but don’t import it themselves will cause a compile-time error. Which is what I want. I want the compiler to tell me about headers that don’t declare their dependencies.

Hopefully this will gradually become history with modules and @import.

#import是一个预处理器指令。它实际上与复制和粘贴相同。因此,如果你先导入 QuartzCore,最后才导入自己头文件,那么在编译之前,所有文件都会在 .m 中展开。这就是为什么顺序很重要。

但是,如果在使用它的其他头文件之前展开它,这些头文件就会意外而非有意地使用它。如果在末尾导入,任何需要它但自己没有导入的头文件都会导致编译时出错。这正是我想要的。我希望编译器能告诉我那些没有声明其依赖关系的头文件。

希望随着模块(modules)和 @import 的使用,这个问题会逐渐成为历史。

好的 #import 顺序

信息披露:以下书籍链接为联盟链接。如果您购买任何商品,我将赚取佣金,您无需支付额外费用。

解决办法很简单:颠倒顺序!从最具体的开始,然后再到最一般的。最重要的是,先包含你自己的头文件。约翰-拉科斯(John Lakos)所著的《大型 C++ 软件设计》是我所知道的唯一一本关于 "物理设计"——如何将源代码编排到文件中的书。

Large-Scale C++ Software Design

该书作者指出:

Latent usage errors can be avoided by ensuring that the .h file of a component parses by itself—without externally-provided declarations or definitions… Including the .h file as the very first line of the .c file ensures that no critical piece of information intrinsic to the physical interface of the component is missing from the .h file (or, if there is, that you will find out about it as soon as you try to compile the .c file).
将 .h 文件作为 .c 文件的第一行,可以确保 .h 文件中不会缺少组件物理接口的关键信息(如果缺少,也不会在编译 .c 文件时发现)。

我是这么做的。如果我在编写 foo.m,我会首先导入 foo.h,并用空行将其与其他导入内容隔开。然后再按顺序导入其他所有导入文件:

#import "foo.h"
#import "abc.h"
#import "def.h"
#import <Abc/Abc.h>

排序可以帮助我找到重复的内容。它还会把角括号导入 <> 放在引号导入之后,这样最一般的标题就会放在最后。

译自:Why #import Order Matters for Dependency Management
侵删

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容