在Objective-C中“导入”和“包含”有什么区别?

在Objective-C中“导入”和“包含”有什么区别?,objective-c,import,include,Objective C,Import,Include,在Objective-C中“导入”和“包含”之间有什么区别?在某些情况下,您是否应该使用其中一种而不是另一种?有人反对吗 我正在阅读以下教程:其中关于“导入和包含”的段落似乎自相矛盾,或者至少不清楚。\include的工作原理与C\include一样 #import跟踪已包含的标头,如果在编译单元中多次导入标头,则会忽略该标头。这使得没有必要使用收割台护罩 底线是只需在Objective-C中使用#import,如果您的标题多次导入某些内容,请不要担心。作为#include的改进版本,将#imp

在Objective-C中“导入”和“包含”之间有什么区别?在某些情况下,您是否应该使用其中一种而不是另一种?有人反对吗

我正在阅读以下教程:其中关于“导入和包含”的段落似乎自相矛盾,或者至少不清楚。

\include
的工作原理与C
\include
一样

#import
跟踪已包含的标头,如果在编译单元中多次导入标头,则会忽略该标头。这使得没有必要使用收割台护罩

底线是只需在Objective-C中使用
#import
,如果您的标题多次导入某些内容,请不要担心。

作为#include的改进版本,将#import指令添加到Objective-C中。然而,它是否有所改善,仍然是一个有争议的问题#导入可确保文件只包含一次,这样就不会出现递归包含问题。然而,无论如何,大多数体面的头文件都会保护自己不受此影响,所以这并没有什么好处

基本上,由您决定使用哪一种。我倾向于#为Objective-C内容(比如类定义等)导入标题,并#包含我需要的标准C内容。例如,我的一个源文件可能如下所示:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>
 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif
#导入
#包括
#包括
#include
它用于将“东西”从另一个文件获取到使用该文件的文件中。 例:

文件中:main.cpp

#include "otherfile.h"

// some stuff here using otherfile.h objects,
// functions or classes declared inside
在每个头文件(*.h)的顶部使用头保护,以防止重复包含同一个文件(如果发生这种情况,将出现编译错误)

文件中:otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif
即使您在代码中放入
#include
“otherfile.h”n次,也不会重新声明其中的内容。

如果在.h文件中包含文件两次,编译器将给出错误。
但是,如果您多次导入一个文件,编译器将忽略它。

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

当编译器看到一个
#include
用包含的文件的内容替换该行时,它会做什么,不问任何问题

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

typedef int my_number;
以及包含以下内容的文件
b.c

#include "a.h"
#include "a.h"
文件
b.c
将在编译前由预处理器翻译为

typedef int my_number;
typedef int my_number;
这将导致编译器错误,因为类型
my_number
定义了两次。即使定义相同,C语言也不允许这样做

由于标题通常用于多个位置,因此C中通常使用包含防护装置。如下所示:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>
 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif
经过预处理后,文件
b.c
中仍然会有两次标题的全部内容。但是第二个实例将被忽略,因为宏
\u a\u h\u included\u
已经被定义

这确实很好,但有两个缺点。首先,必须编写include-guard,并且每个头中的宏名称必须不同。其次,编译器仍然需要查找头文件,并尽可能频繁地读取它

Objy-C具有 <导入> /COD>预处理器指令(它也可以用于C和C++代码,有一些编译器和选项)。这几乎与

#include
相同,但它也会在内部记录已包含的文件。
#import
行仅在第一次遇到命名文件时被其内容替换。每次之后,它都被忽略了

我同意杰森的观点

我在做这件事时被抓住了:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function
#import//使用gettimeofday()函数
#导入//以使用time()函数
对于GNU gcc,它一直抱怨time()函数 没有定义

然后我把“导入”改为“包含”,一切都正常了

原因:

您#导入:
通过使用#defines

您#导入:
不行。即使只包含了部分,如
就导入而言,该文件现在已经完全包含在内。

底线:

传统上,C/C++头包含其他包含文件的部分。
因此,对于C/C++标题,请使用#include.

对于Obj/Objc++头,使用“y.Iputial.

< P>”如果您熟悉C++和宏,那么

#import "Class.h" 
类似于

{
#pragma once

#include "class.h"
}

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

我知道这个线程很旧。。。但在“现代”。。有一种更优越的“包含策略”via——这一点经常被忽视

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

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

要启用模块,请传递命令行标志
-fmodules#include => #import => Precompiled Headers .pch => @import Module(ObjC); => import Module(Swift)
#include + guard == #import