首页 文章

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

提问于
浏览
364

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

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

9 回答

  • 4

    #import指令作为#include的改进版本添加到Objective-C中 . 然而,它是否得到改善仍然是一个争论的问题 . #import确保文件只被包含一次,这样你就不会遇到递归包含问题 . 但是,大多数体面的头文件都可以保护自己不受此影响,所以它并没有那么大的好处 .

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

    #import <Foundation/Foundation.h>
    
    #include <asl.h>
    #include <mach/mach.h>
    
  • 329

    关于预处理器似乎有很多混乱 .

    当编译器看到 #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语言也不允许这样做 .

    由于 Headers 通常用于多个地方,因此通常在C中使用保护 . 这看起来像这样:

    #ifndef _a_h_included_
     #define _a_h_included_
    
     typedef int my_number;
    
     #endif
    

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

    这非常有效,但有两个缺点 . 首先必须编写包含警戒,并且每个 Headers 中的宏名称必须不同 . 其次,编译器仍然需要查找头文件并按原样读取它 .

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

  • 61

    我同意杰森的观点 .

    我抓到了这样做:

    #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>仅使用#defines包含<time.h>的 part

    你#import <time.h>:
    不行 . 尽管只包含<time.h>的一部分,但是
    就#import而言,该文件现在已包含在内了 completely .

    底线:

    C / C头文件传统上包括 parts 其他包含文件 .
    因此,对于C / C头文件,请使用#include .
    对于objc / objc标头,请使用#import .

  • 1

    #include 就像C #include 一样工作 .

    #import 跟踪已包含哪些标头,如果在编译单元中多次导入标头,则会忽略该标头 . 这使得不必使用 Headers 保护 .

    底线只是在Objective-C中使用 #import ,如果您的 Headers 最终导入了多个内容,请不要担心 .

  • 22

    我知道这个帖子已经老了......但是在"modern times" ..有一个远远优于"include strategy"来自clang's @import modules - 这是经常被忽视的..

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

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

    要么

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

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

    要启用模块,请在编译时在 Xcode 中传递命令行标志 -fmodules aka CLANG_ENABLE_MODULES . 如上所述..这种策略避免了任何和所有 LDFLAGS . 如同,你可以删除任何"OTHER_LDFLAGS"设置,以及任何"Linking"阶段..

    enter image description here

    我发现"feel"的编译/启动时间非常快(或者可能,"linking"只有更少的延迟?)..而且,提供了一个很好的机会来清除现在无关的Project-Prefix.pch文件和相应的构建设置, GCC_INCREASE_PRECOMPILED_HEADER_SHARINGGCC_PRECOMPILE_PREFIX_HEADERGCC_PREFIX_HEADER

    此外,虽然没有详细记录......您可以为自己的框架创建 module.map 并以相同的方式包含它们 . You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.

  • 337

    如果您熟悉C和宏,那么

    #import "Class.h"
    

    类似于

    {
    #pragma once
    
    #include "class.h"
    }
    

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

  • 11

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

  • 0

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

  • 1

    #include 它曾经从另一个文件中获取"things"到 #include 使用的文件.Ex:

    in file: main.cpp

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

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

    in file: otherfile.h

    #ifndef OTHERFILE
    #define OTHERFILE
    
    // declare functions, classes or objects here
    
    #endif
    

    即使你在你的代码中放了 #include "otherfile.h"n,这里面的内容也不会被重新声明 .

相关问题