Obtenir l'erreur "Duplicate Interface Definition", doit certainement # importer des files d'en-tête

J'aide sur un projet iOS avec beaucoup de methods et de définitions communes à de nombreuses classs différentes dans AppDelegate. Ainsi, dans chacune de ces classs, dans le file .h, j'utilise #import "AppDelegate.h". Cela fonctionne correctement jusqu'à ce que j'aie besoin d'accéder à l'une de ces classs qui importe déjà AppDelegate dans une autre class qui importe AppDelegate. À ce stade, j'obtiens une erreur de définition d'interface en double pour AppDelegate.

Ok, cela semble juste. J'importe déjà AppDelegate dans un file que j'importe, donc AppDelegate est importé de deux endroits différents. Donc, je supprime la ligne AppDelegate, et tout va bien.

Mais que se passe-t-il lorsque j'ai besoin d'importer deux classs qui doivent toutes deux importer AppDelegate?

J'ai un problème très précis que j'essaie de comprendre, et je sais qu'il est causé par quelque chose qui a à voir avec cela, mais je ne sais pas quoi. J'espère donc comprendre comment je suis censé gérer ce genre d'import, et sortinger tout le rest, et j'espère que cela résoudra mon problème. Donc, pour le dire plus concrètement:

J'ai ClassA.h, ClassB.h et ClassC.h. Tous ont # import "AppDelegate.h". Lorsque j'ai besoin d'utiliser #import "ClassB.h" dans ClassA, je supprime la ligne #import "AppDelegate.h" de ClassA. Tout fonctionne bien. Mais que se passe-t-il si je dois aussi #importer "ClassC.h" dans ClassA, et que ClassB et ClassC NEED ont le #import "AppDelegate.h"?

MODIFIER:

J'ai essayé le scénario exact que j'ai décrit ci-dessus dans un projet propre, et il a bien construit, donc il y a quelque chose d'autre en jeu. Mais ce que je peux dire avec certitude, c'est que lorsque ce problème a été soulevé précédemment avec ce projet, c'était une définition d'interface dupliquée de AppDelegate, et quand j'ai enlevé la ligne #import "AppDelegate.h", l'erreur s'est dissipée. avait access aux methods AppDelegate.h et enums à travers d'autres files importés.

La meilleure prévention et remède pour cela est de suivre quelques directives sur quand importer à partir d'un file d'en-tête. En règle générale, ne jamais importer à partir d'un en-tête Objective-C, sauf dans les cas suivants:

  1. Vous devez étendre une class déclarée dans un autre en-tête.
  2. Vous devez déclarer la conformité à un protocole déclaré dans un autre en-tête.
  3. Vous devez vous référer à un type non-class, non-protocol défini dans un autre en-tête dans les methods publiques et / ou les propriétés. Pour faire reference aux protocoles et classs, transférez-les avec @class ou @protocol , comme @class ClassFromOtherHeader;

Chaque autre #import devrait aller dans votre implémentation. Ma recommandation est de commencer à déplacer toutes vos déclarations #import hors des en-têtes et dans les files d'implémentation selon ces règles. Commencez avec les files que vous pensez être à la racine du problème et déplacez-vous vers l'extérieur. Cela résoudra votre problème et vous donnera l'avantage d'un code plus clair et de time de construction plus rapides.

Pour moi, aucune des réponses ci-dessus n'a aidé, et la réponse donnée ici n'a pas fonctionné.

Ce qui me convenait était de fermer Xcode, d'aller dans ~ / Library / Developer / Xcode / DerivedData et de supprimer toutes datatables dérivées associées à ce projet. Après cela, j'ai rouvert le projet et ça marchait bien.

J'espère que ça aide quelqu'un!

Dans mon cas, aucune des solutions mentionnées n'a résolu le problème. Xcode signalait une interface en double pour une réécriture de class I dans Swift. D'une manière ou d'une autre, le file d'en-tête Objective-C continuait d'être utilisé pour une class qui n'était pas directement référencée dans le projet.

J'ai ouvert le Terminal, cd dans le directory du projet, puis exécuté ce qui suit pour traquer tous les files qui grep -nr ProblemClassName.h . l'en-tête de la class: grep -nr ProblemClassName.h .

Il s'est avéré que l'en-tête de pontage incluait un file obsolète qui n'était même pas référencé dans le browser du projet. Cela importait à son tour les files d'en-tête référencés dans l'erreur Xcode, qui n'étaient pas inclus dans le browser de projet Xcode. Maintenant, je sais ne pas countr uniquement sur le browser de projet Xcode pour les files référencés par l'erreur.

tl; dr Vérifiez l'en-tête de pontage pour vous assurer que tous les files qui y sont importés doivent être présents et qu'ils n'importent pas les en-têtes qui importent les en-têtes du problème.

J'ai trouvé qu'un projet avait un sous-projet et au lieu de referencer les inclusions dans le sous-projet avec la syntaxe correcte:

 #import <SubProject/Filename.h> 

Il les importait directement

 #import <Filename.h> 

Cela n'était possible que parce que le path du sous-projet était inclus dans les «paths de search d'en-tête» du projet principal – ce qui est la mauvaise façon de faire des affaires. Donc, je l'ai supprimé à partir de là. Le sous-projet doit copyr les files inclus nécessaires dans sa section "phases de construction – copyr des files" (ce qui se passait déjà réellement), et la forme appropriée de l'import qui utilise la syntaxe Subproject / Filename.h doit être utilisée.

Fwiw J'ai commencé à le faire apparemment au hasard – pour moi, la solution était de faire du Product->Clean et c'est parti comme par magie.

Pour moi, j'ai oublié d'inclure des parenthèses dans la définition de l'interface dans le file m.