#import和#include在Objective-C中的区别是什么?在某些情况下你应该使用其中一个而不是另一个?一个被弃用了吗?

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


当前回答

#include就像c#中的include一样。

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

底线是在Objective-C中使用#import,不要担心你的头文件会导入一些东西不止一次。

其他回答

如果你在.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中使用。

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

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

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

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

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

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

#import "Class.h" 

类似于

{
#pragma once

#include "class.h"
}

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

我同意杰森的观点。

我这样做被抓了个现行:

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

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

然后我把#import改为#include,一切正常。

原因:

#import <sys/time.h>: <sys/time.h>通过使用#定义只包含<time.h>的一部分

#import <time.h>: 没有去。尽管<time.h>只包含了一部分,as 就#import而言,该文件现在已经完全包含在内。

底线:

C/ c++头文件通常包含其他包含文件的部分。 所以对于C/ c++头文件,使用#include。 对于objc/objc++头文件,使用#import。