在Objective-C中#import和#include之间有什么区别,有时候你应该使用一个而不是另一个吗?一个被弃用了吗?
我正在阅读以下教程:http://www.otierney.net/objective-c.html#preamble及其关于#import和#include的段落似乎自相矛盾或者至少不清楚 .
在Objective-C中#import和#include之间有什么区别,有时候你应该使用一个而不是另一个吗?一个被弃用了吗?
我正在阅读以下教程:http://www.otierney.net/objective-c.html#preamble及其关于#import和#include的段落似乎自相矛盾或者至少不清楚 .
9 回答
#import指令作为#include的改进版本添加到Objective-C中 . 然而,它是否得到改善仍然是一个争论的问题 . #import确保文件只被包含一次,这样你就不会遇到递归包含问题 . 但是,大多数体面的头文件都可以保护自己不受此影响,所以它并没有那么大的好处 .
基本上,由您决定要使用哪个 . 我倾向于#import标头用于Objective-C事物(比如类定义等)和#include标准C我需要的东西 . 例如,我的一个源文件可能如下所示:
关于预处理器似乎有很多混乱 .
当编译器看到
#include
它用所包含文件的内容替换该行时,编译器会做什么,没有问题 .所以如果你有一个带有这个内容的文件
a.h
:和一个包含此内容的文件
b.c
:文件
b.c
将在编译之前由预处理器翻译这将导致编译器错误,因为
my_number
类型定义了两次 . 即使定义相同,C语言也不允许这样做 .由于 Headers 通常用于多个地方,因此通常在C中使用保护 . 这看起来像这样:
在预处理之后,文件
b.c
仍然会将 Headers 的全部内容放入其中两次 . 但是第二个实例将被忽略,因为已经定义了宏_a_h_included_
.这非常有效,但有两个缺点 . 首先必须编写包含警戒,并且每个 Headers 中的宏名称必须不同 . 其次,编译器仍然需要查找头文件并按原样读取它 .
Objective-C具有
#import
预处理器指令(它也可以用于带有一些编译器和选项的C和C代码) . 这与#include
几乎相同,但它也在内部记录了哪些文件已被包含在内 .#import
行仅在遇到第一次时被命名文件的内容替换 . 之后每次都被忽略了 .我同意杰森的观点 .
我抓到了这样做:
对于GNU gcc,它一直抱怨没有定义time()函数 .
然后我将#import改为#include,一切顺利 .
原因:
你#import <sys / time.h>:
<sys / time.h>仅使用#defines包含<time.h>的 part
你#import <time.h>:
不行 . 尽管只包含<time.h>的一部分,但是
就#import而言,该文件现在已包含在内了 completely .
底线:
C / C头文件传统上包括 parts 其他包含文件 .
因此,对于C / C头文件,请使用#include .
对于objc / objc标头,请使用#import .
#include
就像C#include
一样工作 .#import
跟踪已包含哪些标头,如果在编译单元中多次导入标头,则会忽略该标头 . 这使得不必使用 Headers 保护 .底线只是在Objective-C中使用
#import
,如果您的 Headers 最终导入了多个内容,请不要担心 .我知道这个帖子已经老了......但是在"modern times" ..有一个远远优于"include strategy"来自clang's @import modules - 这是经常被忽视的..
要么
要启用模块,请在编译时在
Xcode
中传递命令行标志-fmodules
akaCLANG_ENABLE_MODULES
. 如上所述..这种策略避免了任何和所有LDFLAGS
. 如同,你可以删除任何"OTHER_LDFLAGS"设置,以及任何"Linking"阶段..我发现"feel"的编译/启动时间非常快(或者可能,"linking"只有更少的延迟?)..而且,提供了一个很好的机会来清除现在无关的Project-Prefix.pch文件和相应的构建设置,
GCC_INCREASE_PRECOMPILED_HEADER_SHARING
,GCC_PRECOMPILE_PREFIX_HEADER
和GCC_PREFIX_HEADER
等此外,虽然没有详细记录......您可以为自己的框架创建
module.map
并以相同的方式包含它们 . You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.如果您熟悉C和宏,那么
类似于
这意味着当您的应用运行时,您的类只会加载一次 .
如果你在.h文件中#include一个文件两次比编译器会给出错误 . 但是如果#import一个文件不止一次,编译器就会忽略它 .
在可能的情况下,我的一个
.h
文件中有一个全局变量导致了问题,我通过在它前面添加extern
来解决它 .#include
它曾经从另一个文件中获取"things"到#include
使用的文件.Ex:in file: main.cpp
在每个头文件(* .h)的顶部使用头部保护,以防止包含相同的文件多一次(如果它发生,您将得到编译错误) .
in file: otherfile.h
即使你在你的代码中放了
#include
"otherfile.h"n,这里面的内容也不会被重新声明 .