【问题标题】:Getting "Duplicate Interface Definition" error, definitely has to #import ing header files出现“重复接口定义”错误,肯定要 #import 头文件
【发布时间】:2012-09-07 02:23:00
【问题描述】:

我正在帮助一个 iOS 项目,其中包含许多 AppDelegate 中许多不同类共有的方法和定义。因此,在每个类中,在 .h 文件中,我使用 #import "AppDelegate.h"。这工作正常,直到我需要访问已经将 AppDelegate 导入另一个导入 AppDelegate 的类中的一个类。此时,我收到 AppDelegate 的重复接口定义错误。

好的,这看起来很公平。我已经将 AppDelegate 导入到我正在导入的文件中,因此 AppDelegate 正在从两个不同的地方导入。所以我删除了 AppDelegate 行,一切都很好。

但是当我需要导入两个都需要导入 AppDelegate 的类时会发生什么?

我有一个非常具体的问题,我正试图解决这个问题,我知道它是由与此有关的某些事情引起的,但我不确定是什么。所以我希望我能弄清楚我应该如何处理这种导入,并将其他所有内容整理出来,并希望这能解决我的问题。因此,更具体地说:

我有 ClassA.h、ClassB.h 和 ClassC.h。都有#import“AppDelegate.h”。当我需要在 ClassA 中使用 #import "ClassB.h" 时,我会从 ClassA 中删除 #import "AppDelegate.h" 行。一切顺利。但是如果我还需要#import "ClassC.h" 到 ClassA 中,但 ClassB 和 ClassC 需要有 #import "AppDelegate.h" 会发生什么?

编辑:

我在一个干净的项目中尝试了我上面描述的确切场景,它构建得很好,所以还有其他东西在起作用。但是我可以肯定地说,这个问题之前在这个项目中出现的时候,是一个重复的AppDelegate接口定义,当我删除#import“AppDelegate.h”这一行时,错误消失了,我仍然可以通过其他导入的文件访问 AppDelegate.h 方法和枚举。

【问题讨论】:

  • 您确定您使用的是#import 而不是#include 吗? #import 设计为永远不会两次导入相同的头文件,因此编译器 #import "AppDelegate.h" 两次似乎不合逻辑
  • 100% 确定。我的谷歌研究也说了同样的话。过去我遇到过类似的问题,我可以通过将文件包含在 .m 而不是 .h 中来解决这个问题,但不幸的是,我需要访问导入 .h 中导入文件中的枚举,所以这不是一个选择。
  • 但是我刚刚制作了一个示例应用程序,完全符合我在底部描述的场景,并且它有效。所以我想这里还有别的东西在起作用。但是我可以肯定的说,以前这个问题出现的时候,是AppDelegate的重复接口定义,当我去掉#import "AppDelegate.h"这一行,错误就消失了,我还是有通过其他导入文件访问 AppDelegate.h 方法和枚举。
  • 将枚举写入单独的 *.h 文件并在需要的地方导入它们。
  • 但是我还需要使用AppDelegate中的方法。那我应该在 .m 文件中导入 AppDelegate 吗?

标签: objective-c ios xcode


【解决方案1】:

最好的预防和治疗方法是遵循一些关于何时从头文件导入的准则。作为一般规则,切勿从 Objective-C 标头导入,除非在以下情况下:

  1. 您需要扩展在另一个标头中声明的类。
  2. 您需要声明符合在另一个声明中声明的协议 标题。
  3. 您需要在公共方法和/或属性中引用另一个头文件中定义的非类、非协议类型。要引用协议和类,请使用 @class@protocol 前向声明它们,例如 @class ClassFromOtherHeader;

其他所有#import 都应该加入您的实现。我的建议是根据这些规则开始将所有#import 语句从标题中移出并放入实现文件中。从您认为是问题根源的文件开始,然后向外移动。这将解决您的问题,并为您带来更清晰的代码和更快的构建时间。

【讨论】:

  • 感谢您提供这些指南。他们肯定对了解很有帮助。我检查并清理了代码,在大多数情况下,我能够将大量#imports 移动到.m 中。但是,我无法完全解决这个问题。由于需要定义,几乎每个类都需要导入 AppDelegate.h 和其他两个类。构建导致 AppDelegate 弹出相同的重复接口定义错误。我突然想到,其中一些导入 AppDelegate.h 的文件被导入了 AppDelegate.m。这可能是问题吗?
  • @CowGoes 不客气,这可能是问题的一部分。还要仔细检查你没有在任何地方错误地使用#include。我更新了我的答案,以更具体地说明前向声明 - 对你的前向声明无情。你们是否都在使用任何版本控制,您可以在其中查看您的更改并缩小导致问题的特定导入指令的范围?
  • 我实际上刚刚解决了这个问题——原来项目中实际上包含了另一个 AppDelegate.h。在我之前从事这个项目的那个人我猜是不分青红皂白地从其他项目中复制东西。但我想这是因祸得福,因为现在我知道在实现和头文件中导入的正确协议。
  • @CowGoes 哦,那些工程师之一;)很高兴我的回答有帮助,祝项目好运!
  • 非常有帮助的答案。最后四行解决了我的问题。当然值得一票。
【解决方案2】:

Fwiw 我开始看似随机地得到这个 - 对我来说,修复是做 Product->Clean 并且它神奇地消失了。

【讨论】:

    【解决方案3】:

    对我来说,以上答案都没有帮助,here 给出的答案也不起作用。

    为我解决的问题是关闭 Xcode,转到 ~/Library/Developer/Xcode/DerivedData 并删除与该项目关联的所有派生数据。之后我重新打开了这个项目,它工作正常。

    希望对某人有所帮助!

    【讨论】:

    • 有同样的问题,这是唯一对我有用的解决方案。在 Finder 中移动一堆文件然后更新 Xcode 项目后,问题就出现了。
    • 这对我有用。我删除了所有名为 myfile.o 的文件,其中 myfile 是发生警告的 .h 文件的名称:
    • @poff,这为我在 iOS 9 上的简单项目抬起了丑陋的头 - 你的修复仍然有效。谢谢
    【解决方案4】:

    就我而言,上述解决方案均未解决此问题。 Xcode 报告了我在 Swift 中重写的类的重复接口。不知何故,它不断为项目中未直接引用的类拉入 Objective-C 头文件。

    我打开终端,cd 进入项目目录,然后运行以下命令来追踪包含类头文件的所有文件: grep -nr ProblemClassName.h .

    事实证明,桥接头包含一个过时的文件,该文件甚至没有在项目导航器中引用。这反过来又导入了 Xcode 错误中引用的头文件,这些头文件也不包含在 Xcode 项目导航器中。现在我知道不能只依赖 Xcode 项目导航器来查找错误引用的文件。

    tl;dr 仔细检查桥接头以确保所有导入的文件都应该在那里,并且没有导入反过来导入问题标头的标头。

    【讨论】:

      【解决方案5】:

      我发现一个项目有一个子项目,而不是用正确的语法引用子项目中的包含:

      #import <SubProject/Filename.h>
      

      直接导入

      #import <Filename.h>
      

      这只是可能的,因为子项目的路径包含在主项目的“标题搜索路径”中 - 这是错误的业务方式。所以我从那里删除了它。 子项目应在其“构建阶段 - 复制文件”部分复制所需的包含文件(这实际上已经发生),并且应使用使用 Subproject/Filename.h 语法的正确导入形式。

      【讨论】:

        【解决方案6】:

        对我来说,我忘了在 m 文件的接口定义中包含括号。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-26
          • 1970-01-01
          • 1970-01-01
          • 2016-12-10
          • 1970-01-01
          • 1970-01-01
          • 2011-02-27
          • 1970-01-01
          相关资源
          最近更新 更多