ios 出现“重复的接口定义”错误,一定要#import 头文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12415720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:06:42  来源:igfitidea点击:

Getting "Duplicate Interface Definition" error, definitely has to #import ing header files

objective-ciosxcode

提问by CowGoes

I'm helping on an iOS project with lots of methods and definitions common to many different classes in the AppDelegate. So, in each of those classes, in the .h file, I use #import "AppDelegate.h". This works fine until I need access to one of those classes that already imports the AppDelegate into another class that imports AppDelegate. At this point, I get a Duplicate Interface Definition error for AppDelegate.

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

Ok, so that seems fair. I'm already importing AppDelegate into a file that I'm importing, so AppDelegate is getting imported from two different places. So I remove the AppDelegate line, and everything is fine.

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

But what happens when I need to import two classes that both need to import AppDelegate?

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

I have a very specific problem that I'm trying to wrap my head around, and I know it is being caused by something that has to do with this, but I'm not sure what. So I'm hoping if I figure out how I'm supposed to be handling this sort of importing, and sort everything else out, and hope that this solves my problem. So to put this in more concrete terms:

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

I have ClassA.h, ClassB.h, and ClassC.h. All have #import "AppDelegate.h". When I need to use #import "ClassB.h" in ClassA, I remove the #import "AppDelegate.h" line from ClassA. Everything works smoothly. But what happens if I also need to #import "ClassC.h" into ClassA, and but ClassB and ClassC NEED to have the #import "AppDelegate.h"?

我有 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" 会发生什么?

EDIT:

编辑:

I tried the exact scenario I described above in a clean project, and it built fine, so there is something else at play. But what I can say with certainty is that when this issue came up previously with this project, it was a duplicate interface definition of AppDelegate, and when I removed the #import "AppDelegate.h" line, the error went away, and I still had access to the AppDelegate.h methods and enums through other imported files.

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

回答by Carl Veazey

The best prevention and cure for this is to follow some guidelines on when to import from a header file. As a general rule, never import from an Objective-C header except in these cases:

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

  1. You need to extend a class declared in another header.
  2. You need to declare conformity with a protocol declared in another header.
  3. You need to refer to a non-class, non-protocol type defined in another header in the public methods and / or properties. To refer to protocols and classes, forward declare them with @classor @protocol, like @class ClassFromOtherHeader;
  1. 您需要扩展在另一个标头中声明的类。
  2. 您需要声明与另一个标头中声明的协议的一致性。
  3. 您需要引用公共方法和/或属性中另一个标头中定义的非类、非协议类型。指协议和类,向前声明它们@class@protocol@class ClassFromOtherHeader;

Every other #importshould go in your implementation. My recommendation is to start moving all your #importstatements out of headers and into the implementation files according to these rules. Start with the files you think are at the root of the problem and move outward. This will fix your problem and give you the side benefit of clearer code and faster build times.

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

回答by poff

For me none of the above answers were helping, nor did the answer given herework.

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

What fixed it for me was closing Xcode, going to ~/Library/Developer/Xcode/DerivedData and deleting all of the derived data associated with this project. After that I reopened the project and it was working fine.

对我来说修复它的是关闭 Xcode,转到 ~/Library/Developer/Xcode/DerivedData 并删除与该项目关联的所有派生数据。之后,我重新打开了该项目,它运行良好。

Hope that helps someone!

希望对某人有所帮助!

回答by Andrew

In my case, none of the solutions mentioned fixed the issue. Xcode was reporting a duplicate interface for a class I rewrote in Swift. Somehow it kept pulling in the Objective-C header file for a class that wasn't directly referenced in the project.

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

I opened the Terminal, cdinto the project directory, then ran the following to track down any files that were including the class header: grep -nr ProblemClassName.h .

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

It turned out that the bridging header included an obsolete file that wasn't even referenced in the project navigator. That in turn was importing the header files referenced in the Xcode error, that were also not included in the Xcode project navigator. Now I know to not rely only on the Xcode project navigator for files referenced by the error.

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

tl;drDouble check the bridging header to ensure that all files that are imported there should be there and are not importing headers that are in-turn importing the problem headers.

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

回答by Andy Weinstein

I found that a project had a subproject and instead of referencing the includes in the subproject with the proper syntax:

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

#import <SubProject/Filename.h>

It was directly importing them

它是直接导入它们

#import <Filename.h>

This was only possible because the path of the subproject was included in the "header search paths" of the main project - which is the wrong way to do business. So I deleted it from there. The subproject should copy the needed included files in its "build phases - copy files" section (which was already happening actually), and the proper form of import that uses the Subproject/Filename.h syntax should be used.

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

回答by ahmad zen

For me, I forgot to include parenthesis in interface definition in m file.

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

回答by canhazbits

Fwiw I started getting this seemingly at random - for me the fix was to do Product->Cleanand it magically went away.

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