Objective-C 中的#import 和#include 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/439662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:02:42  来源:igfitidea点击:

What is the difference between #import and #include in Objective-C?

objective-cimportinclude

提问by Ryan Guill

What are the differences between #import and #include in Objective-C and are there times where you should use one over the other? Is one deprecated?

Objective-C 中#import 和#include 之间的区别是什么?有时您应该使用一个而不是另一个?一个被弃用了吗?

I was reading the following tutorial: http://www.otierney.net/objective-c.html#preambleand its paragraph about #import and #include seems to contradict itself or at least is unclear.

我正在阅读以下教程:http: //www.otierney.net/objective-c.html#preamble 及其关于#import 和#include 的段落似乎自相矛盾或至少不清楚。

采纳答案by Jason Coco

The #import directive was added to Objective-C as an improved version of #include. Whether or not it's improved, however, is still a matter of debate. #import ensures that a file is only ever included once so that you never have a problem with recursive includes. However, most decent header files protect themselves against this anyway, so it's not really that much of a benefit.

#import 指令作为#include 的改进版本添加到Objective-C 中。然而,它是否有所改善,仍然是一个有争议的问题。#import 确保一个文件只被包含一次,这样你就不会遇到递归包含的问题。然而,无论如何,大多数体面的头文件都会保护自己免受这种情况的影响,所以这并不是真正的好处。

Basically, it's up to you to decide which you want to use. I tend to #import headers for Objective-C things (like class definitions and such) and #include standard C stuff that I need. For example, one of my source files might look like this:

基本上,由您决定要使用哪个。我倾向于为 Objective-C 的东西(比如类定义等)#import 标头,并#include 我需要的标准 C 东西。例如,我的源文件之一可能如下所示:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>

回答by Sven

There seems to be a lot of confusion regarding the preprocessor.

关于预处理器似乎有很多困惑。

What the compiler does when it sees a #includethat it replaces that line with the contents of the included files, no questions asked.

编译器在看到#include它用包含文件的内容替换该行时会做什么,没有问题。

So if you have a file a.hwith this contents:

因此,如果您有一个a.h包含以下内容的文件:

typedef int my_number;

and a file b.cwith this content:

和一个b.c包含此内容的文件:

#include "a.h"
#include "a.h"

the file b.cwill be translated by the preprocessor before compilation to

该文件b.c将在编译前由预处理器翻译成

typedef int my_number;
typedef int my_number;

which will result in a compiler error, since the type my_numberis defined twice. Even though the definition is the same this is not allowed by the C language.

这将导致编译器错误,因为类型my_number被定义了两次。即使定义相同,这也是 C 语言所不允许的。

Since a header often is used in more than one place include guardsusually are used in C. This looks like this:

由于标头经常在不止一个地方使用,因此 C 中通常会使用包含守卫。这看起来像这样:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

The file b.cstill would have the whole contents of the header in it twice after being preprocessed. But the second instance would be ignored since the macro _a_h_included_would already have been defined.

b.c经过预处理后,该文件仍将包含两次标题的全部内容。但是第二个实例将被忽略,因为宏_a_h_included_已经被定义了。

This works really well, but has two drawbacks. First of all the include guards have to be written, and the macro name has to be different in every header. And secondly the compiler has still to look for the header file and read it as often as it is included.

这非常有效,但有两个缺点。首先,必须编写包含守卫,并且每个标头中的宏名称必须不同。其次,编译器仍然需要查找头文件并在包含时经常读取它。

Objective-C has the #importpreprocessor instruction (it also can be used for C and C++ code with some compilers and options). This does almost the same as #include, but it also notes internally which file has already been included. The #importline is only replaced by the contents of the named file for the first time it is encountered. Every time after that it is just ignored.

Objective-C 具有#import预处理器指令(它还可以用于带有一些编译器和选项的 C 和 C++ 代码)。这与 几乎相同#include,但它也在内部注明已经包含了哪个文件。该#import行仅在第一次遇到时被命名文件的内容替换。之后每次都会被忽略。

回答by user512705

I agree with Jason.

我同意杰森。

I got caught out doing this:

我被抓到这样做:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function

For GNU gcc, it kept complaining that time() function was not defined.

对于 GNU gcc,它一直抱怨没有定义 time() 函数。

So then I changed #import to #include and all went ok.

然后我将#import 更改为#include,一切顺利。

Reason:

原因:

You #import <sys/time.h>:
    <sys/time.h> includes only a partof <time.h> by using #defines

您 #import <sys/time.h>:
    <sys/time.h>使用 #defines仅包含<time.h>的一部分

You #import <time.h>:
    No go. Even though only part of <time.h> was already included, as
    far as #import is concerned, that file is now already completelyincluded.

你#import <time.h>:
    不行。尽管仅包含 <time.h> 的一部分,但
    就 #import 而言,该文件现在已经完全包含在内。

Bottom line:

底线:

C/C++ headers traditionally includes partsof other include files.
So for C/C++ headers, use #include.
For objc/objc++ headers, use #import.

C / C ++传统上标头包括部件的其他包含文件。
所以对于 C/C++ 头文件,使用 #include。
对于 objc/objc++ 头文件,使用 #import。

回答by Ferruccio

#includeworks just like the C #include.

#include就像 C 一样工作#include

#importkeeps track of which headers have already been included and is ignored if a header is imported more than once in a compilation unit. This makes it unnecessary to use header guards.

#import跟踪已包含哪些头文件,如果在编译单元中多次导入头文件,则将其忽略。这使得没有必要使用标题保护。

The bottom line is just use #importin Objective-C and don't worry if your headers wind up importing something more than once.

底线只是#import在 Objective-C 中使用,不要担心您的头文件是否会多次导入某些内容。

回答by Alex Gray

I know this thread is old... but in "modern times".. there is a far superior "include strategy" via clang's @importmodules- that is oft-overlooked..

我知道这个线程很旧……但是在“现代”中……通过clang 的@import模块有一个非常优越的“包含策略” ——这经常被忽视。

Modules improve access to the API of software libraries by replacing the textual preprocessor inclusion model with a more robust, more efficient semantic model. From the user's perspective, the code looks only slightly different, because one uses an import declaration rather than a #include preprocessor directive:

模块通过用更健壮、更高效的语义模型替换文本预处理器包含模型来改进对软件库 API 的访问。从用户的角度来看,代码看起来只是略有不同,因为使用导入声明而不是 #include 预处理器指令:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

or

或者

@import Foundation;  //  Like #import <Foundation/Foundation.h>
@import ObjectiveC;  //  Like #import <objc/runtime.h>

However, this module import behaves quite differently from the corresponding #include: when the compiler sees the module import above, it loads a binary representation of the module and makes its API available to the application directly. Preprocessor definitions that precede the import declaration have no impact on the API provided... because the module itself was compiled as a separate, standalone module. Additionally, any linker flags required to use the module will automaticallybe provided when the module is imported. This semantic import model addresses many of the problems of the preprocessor inclusion model.

但是,此模块导入的行为与相应的 #include 完全不同:当编译器看到上面的模块导入时,它会加载模块的二进制表示,并使其 API 直接可用于应用程序。导入声明之前的预处理器定义对提供的 API 没有影响......因为模块本身被编译为单独的独立模块。此外,导入模块时将自动提供使用模块所需的任何链接器标志。这种语义导入模型解决了预处理器包含模型的许多问题。

To enable modules, pass the command-line flag -fmodulesaka CLANG_ENABLE_MODULESin Xcode- at compile time. As mentioned above.. this strategy obviates ANY and ALL LDFLAGS. As in, you can REMOVE any "OTHER_LDFLAGS" settings, as well as any "Linking" phases..

要启用模块,请在编译时传递命令行标志-fmodulesaka CLANG_ENABLE_MODULESin Xcode-。如上所述.. 这个策略排除了 ANY 和 ALL LDFLAGS。如在,您可以删除任何“OTHER_LDFLAGS”设置,以及任何“链接”阶段..

enter image description here

在此处输入图片说明

I find compile / launch times to "feel" much snappier (or possibly, there's just less of a lag while "linking"?).. and also, provides a great opportunity to purge the now extraneous Project-Prefix.pch file, and corresponding build settings, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, and GCC_PREFIX_HEADER, etc.

我发现编译/启动时间“感觉”更快速(或者可能,“链接”时延迟更少?)..而且,提供了一个很好的机会来清除现在无关的 Project-Prefix.pch 文件,并且相应的构建设置GCC_INCREASE_PRECOMPILED_HEADER_SHARINGGCC_PRECOMPILE_PREFIX_HEADER以及GCC_PREFIX_HEADER

Also, while not well-documented… You can create module.maps for your own frameworks and include them in the same convenient fashion. You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.

此外,虽然没有很好的文档......您可以module.map为自己的框架创建s 并以同样方便的方式包含它们。 您可以查看我的 ObjC-Clang-Modules github 存储库,了解如何实现此类奇迹的一些示例。

回答by Evol Gate

If you are familiar with C++ and macros, then

如果您熟悉 C++ 和宏,那么

#import "Class.h" 

is similar to

类似于

{
#pragma once

#include "class.h"
}

which means that your Class will be loaded only once when your app runs.

这意味着当您的应用程序运行时,您的类只会被加载一次。

回答by neowinston

In may case I had a global variable in one of my .hfiles that was causing the problem, and I solved it by adding externin front of it.

在可能的情况下,我的一个.h文件中有一个导致问题的全局变量,我通过extern在它前面添加来解决它。

回答by yoAlex5

#include + guard == #import

#include guardWiki- macro guard, header guard or file guard prevents to double include a header by a preprocessorthat can slow down a build time

#include guardWiki- 宏保护、标题保护或文件保护可防止通过preprocessor可能减慢构建时间的双重包含标题

The next step is

下一步是

.pch[About]=> @import[About]

.pch[关于]=>@import[关于]

[#import in .hor .m]

[#import in.h.m]

回答by Celso Dantas

#includeit used to get "things" from another file to the one the #includeis used in. Ex:

#include它曾经从另一个文件中获取“东西”到使用的那个文件#include。例如:

in file: main.cpp

在文件中:main.cpp

#include "otherfile.h"

// some stuff here using otherfile.h objects,
// functions or classes declared inside

Header guard is used on the top of each header file (*.h) to prevent including the same file more then once (if it happens you will get compile errors).

头文件保护用于每个头文件 (*.h) 的顶部,以防止多次包含同一文件(如果发生,您将收到编译错误)。

in file: otherfile.h

在文件中:otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif

even if you put #include"otherfile.h" n time in your code, this inside it will not be redeclared.

即使您#include在代码中放置了n 次“otherfile.h”,它也不会被重新声明。

回答by Husmukh

IF you #include a file two times in .h files than compiler will give error. But if you #import a file more than once compiler will ignore it.

如果你在 .h 文件中 #include 一个文件两次,编译器就会出错。但是如果你多次#import 一个文件,编译器会忽略它。