#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的段落似乎自相矛盾,至少不清楚。
当前回答
如果您熟悉c++和宏,那么
#import "Class.h"
类似于
{
#pragma once
#include "class.h"
}
这意味着当你的应用程序运行时,你的类只会被加载一次。
其他回答
#import指令作为#include的改进版本被添加到Objective-C中。然而,它是否有所改善仍是一个争论的问题。#import确保一个文件只被包含一次,这样就不会出现递归包含的问题。然而,大多数体面的头文件都会保护自己不受这种情况的影响,所以这并没有什么好处。
基本上,由您决定使用哪一种。我倾向于#import Objective-C内容(如类定义等)的头文件,#包含我需要的标准C内容。例如,我的一个源文件可能是这样的:
#import <Foundation/Foundation.h>
#include <asl.h>
#include <mach/mach.h>
#include用于从另一个文件中获取“东西”到使用#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次,其中的this也不会被重新声明。
#include vs #import预处理器指令
历史:
#include -> #import ->[预编译Headers .pch] -> [@import Module(ObjC);] -> [import Module(Swift)]
#import是#include的下一代,它解决了当前.h文件的双重包含和递归包含问题。只是当前文件中包含的。h主体的单一副本
#import == #include + guard
守卫长这样
#ifndef <some_unique_name>
#define <some_unique_name>
<header_body>
#endif
#include guardWiki(宏保护,头保护,文件保护)-防止预处理器包含多个头,这会减慢构建时间
#include和#import使用了一种复制/粘贴机制——递归地复制.h文件主体(除了#include, #import指令之外的所有内容)。这意味着结果文件将不包含#include, #import指令)
如果选择。m文件Product -> Perform Action ->预处理“。m”,可以检查结果。
# include示例
//A.h
@interface A : NSObject
- (int)startA;
@end
//ViewController.h
#include "A.h"
ViewController。M预处理后
@interface A : NSObject
- (int)startA;
@end
@interface ViewController : UIViewController
@end
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
}
@end
双重包含示例
//A.h
@interface A : NSObject //Build time error: Duplicate interface definition for class 'A'
@end
//B.h
#include "A.h"
//C.h
#include "A.h"
//#import "A.h" to solve
#include "B.h"
递归包含示例
//A.h
#include "B.h" //Build time error: #include nested too deeply
//#import "B.h" to fix it
@interface B : NSObject //Build time error: Duplicate interface definition for class 'A'
@end
//B.h
#include "A.h" //Build time error: #include nested too deeply
//#import "A.h" to fix it
@interface B : NSObject //Build time error: Duplicate interface definition for class 'B'
@end
[#import in .h or .m]
如果你在.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行只有在第一次遇到命名文件时才会被该文件的内容替换。之后的每一次都被忽略了。