【问题标题】:Importing header in objective c在目标 c 中导入标头
【发布时间】:2012-05-10 10:09:44
【问题描述】:

在 Objective-c 中,当我们按照约定将一个类的对象用于另一个类时,我们应该在 .h 文件中前向声明该类,即@class classname;。并且应该在.m文件中导入头文件,即#import "header.h"。 但是如果我们在 .h 中导入头文件,那么我们不必在 .m 文件中再次导入它。 那么这个约定背后的原因是什么?哪种方式有效?

【问题讨论】:

    标签: objective-c ios forward-declaration build-time


    【解决方案1】:

    那么这个约定背后的原因是什么?

    您应该在可能的情况下支持前向声明 (@class MONClass;),因为编译器在使用它之前需要知道类型名是 objc 类,并且因为 #import 可以拖入大量其他头文件(例如整个框架/libraries),严重扩展和复杂化您的依赖项并增加构建时间。

    哪种方式有效?

    转发声明。如果您正确执行此操作,您的构建、重建和索引将快得多

    【讨论】:

    • 所以澄清一下,如果我在 .h 文件中声明一个类型,我会使用 @classname 转发声明,然后在我向对象发送消息的 .m 文件中导入实际的头文件“类名.h" ?
    • @conor 正确。不过,还有更多细节:stackoverflow.com/questions/322597/class-vs-import/… 在过去几年中,编译器的进步和语言的变化(在 ObjC 中)使得将类的依赖项排除在标题之外变得更加容易——它都可以放在 @ 987654324@ 在很多情况下。所以你需要你的超类和你公开采用的任何协议。您的 ivars 和属性通常可以不在标题中 - 在这些情况下不需要导入或转发。
    【解决方案2】:

    您是正确的,在 .h 中导入标头会更容易(在短期内)。不这样做并将其导入实现文件 (.m) 的原因是为了防止名称污染,当有人导入您的标头时,导入标头中的所有名称都可用。相反,通过导入您的标头,只应导入您的函数/类,其余的在实现中

    此外,如果您在 .h 中导入标头,这意味着当第 3 方标头更改时,导入您的标头的每个代码都必须重新编译,即使您的标头中没有显式更改。前向声明避免了这个问题,并且只强制重新编译那些实际使用 3rd-party 标头的实现 (.m) 文件

    【讨论】:

      【解决方案3】:

      虽然在 .m 中导入文件可以更轻松地摆脱几行代码,但一般认为导入可能会影响加载时间和响应时间,是的,它确实会影响并且不会。因为根据文档苹果:-

      如果您担心包含主头文件可能会导致您的程序膨胀,请不要担心。因为 Mac OS X 接口是使用框架实现的,所以这些接口的代码驻留在动态共享库中,而不是在您的可执行文件中。此外,只有您的程序使用的代码会在运行时加载到内存中,因此您的内存占用空间同样很小。

      至于编译时包含大量的头文件,再一次,不用担心。 Xcode 提供了一个预编译头工具来加快编译时间。通过一次编译所有框架头文件,除非您添加新框架,否则无需重新编译头文件。同时,您可以使用所包含框架中的任何接口,而不会或几乎没有性能损失。

      因此响应和加载时间仅在第一次受到影响,但无论如何,前向引用应该有利于维护编码标准并避免开销,无论多么小:)。

      【讨论】:

        【解决方案4】:

        #import 是一个预处理器指令,它在编译器看到文件之前对其进行操作。每当您感到困惑时,在概念上将其视为复制粘贴:当您看到#import foo 时,意味着文件 foo 的内容已插入该点。 (比这更聪明一点,因为它还可以防止重复包含)。

        如果Bar.h 中有引用Foo.h 的声明,那么你#import Foo.hBar.h 中。如果 Bar.h 中没有使用 Foo 的内容,但有 Bar.m,则导入进入 Bar.m。仅在需要的地方保留声明。

        【讨论】:

          【解决方案5】:

          这只是说编译器我们有一个名为 xx 的类,如果你使用 @class xx;

          因为您现在不需要它的属性/方法。

          在下一种情况下,您还需要属性和方法,因为您必须访问它们。如果您在 .h 文件中使用 @class xx 并且不导入 xx.h,这就是问题所在。那么声明xx的对象不会产生错误,但是访问它的方法会产生警告,访问属性会产生错误

          【讨论】:

          • 我讨厌苛刻,但如果您在句子开头使用大写字母并且不使用非标准缩写/拼写,例如' becz'、'cz' 和 'rite'。
          猜你喜欢
          • 2019-05-07
          • 1970-01-01
          • 2022-08-16
          • 1970-01-01
          • 1970-01-01
          • 2019-12-29
          • 2015-01-24
          • 2015-08-16
          • 1970-01-01
          相关资源
          最近更新 更多