21

我正在帮助一个 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 方法和枚举。

4

6 回答 6

29

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

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

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

于 2012-09-13T23:00:01.403 回答
21

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

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

希望对某人有所帮助!

于 2014-04-28T18:18:51.493 回答
3

就我而言,提到的解决方案都没有解决这个问题。Xcode 报告了我在 Swift 中重写的类的重复接口。不知何故,它一直在为一个在项目中没有直接引用的类拉入 Objective-C 头文件。

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

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

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

于 2015-11-09T20:17:58.330 回答
1

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

#import <SubProject/Filename.h>

它是直接导入它们

#import <Filename.h>

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

于 2017-03-21T14:28:40.057 回答
0

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

于 2013-05-22T02:40:50.997 回答
0

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

于 2017-11-13T09:41:44.907 回答