#import和#include在Objective-C中的区别是什么?在某些情况下你应该使用其中一个而不是另一个?一个被弃用了吗?
我正在阅读以下教程:http://www.otierney.net/objective-c.html#preamble,其中关于#import和#include的段落似乎自相矛盾,至少不清楚。
#import和#include在Objective-C中的区别是什么?在某些情况下你应该使用其中一个而不是另一个?一个被弃用了吗?
我正在阅读以下教程:http://www.otierney.net/objective-c.html#preamble,其中关于#import和#include的段落似乎自相矛盾,至少不清楚。
当前回答
#include就像c#中的include一样。
#import跟踪哪些头文件已经被包含,如果一个头文件在编译单元中被导入多次,则该头文件将被忽略。这使得没有必要使用头保护。
底线是在Objective-C中使用#import,不要担心你的头文件会导入一些东西不止一次。
其他回答
#include就像c#中的include一样。
#import跟踪哪些头文件已经被包含,如果一个头文件在编译单元中被导入多次,则该头文件将被忽略。这使得没有必要使用头保护。
底线是在Objective-C中使用#import,不要担心你的头文件会导入一些东西不止一次。
如果您熟悉c++和宏,那么
#import "Class.h"
类似于
{
#pragma once
#include "class.h"
}
这意味着当你的应用程序运行时,你的类只会被加载一次。
我知道这个帖子很旧…但在“现代”…通过clang的@import模块有一个更优秀的“包含策略”-这经常被忽视。
模块通过将文本预处理器包含模型替换为更健壮、更高效的语义模型,改进了对软件库API的访问。从用户的角度来看,代码看起来只是略有不同,因为使用了import声明而不是#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 automatically be provided when the module is imported. This semantic import model addresses many of the problems of the preprocessor inclusion model.
要启用模块,在编译时传递命令行标志-fmodules,也就是Xcode中的CLANG_ENABLE_MODULES。如上所述…该策略避免了任何和所有ldflag。正如在,你可以删除任何“OTHER_LDFLAGS”设置,以及任何“链接”阶段..
我发现编译/启动时间“感觉”更迅速(或者可能,在“链接”时延迟更少?)..同时,也提供了一个很好的机会来清除现在多余的Project-Prefix。pch文件,以及相应的构建设置,gcc_incree_precompiled_header_sharing, GCC_PRECOMPILE_PREFIX_HEADER, GCC_PREFIX_HEADER等。
此外,虽然没有良好的文档…映射到您自己的框架,并以同样方便的方式包含它们。你可以看看我的ObjC-Clang-Modules github回购的一些例子,如何实现这样的奇迹。
#import指令作为#include的改进版本被添加到Objective-C中。然而,它是否有所改善仍是一个争论的问题。#import确保一个文件只被包含一次,这样就不会出现递归包含的问题。然而,大多数体面的头文件都会保护自己不受这种情况的影响,所以这并没有什么好处。
基本上,由您决定使用哪一种。我倾向于#import Objective-C内容(如类定义等)的头文件,#包含我需要的标准C内容。例如,我的一个源文件可能是这样的:
#import <Foundation/Foundation.h>
#include <asl.h>
#include <mach/mach.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行只有在第一次遇到命名文件时才会被该文件的内容替换。之后的每一次都被忽略了。