Получение ошибки "Duplicate Interface Definition", безусловно, должно содержать #importing заголовочные файлы
Я помогаю проекту iOS с множеством методов и определений, общих для многих классов в AppDelegate. Таким образом, в каждом из этих классов в файле .h я использую #import "AppDelegate.h" . Это отлично работает, пока мне не нужен доступ к одному из тех классов, которые уже импортируют AppDelegate в другой класс, который импортирует AppDelegate. На этом этапе я получаю ошибку Duplicate Interface Definition для AppDelegate.
Хорошо, так что это справедливо. Я уже импортирую AppDelegate в файл, который я импортирую, поэтому AppDelegate импортируется из двух разных мест. Поэтому я удаляю строку AppDelegate, и все в порядке.
Но что происходит, когда мне нужно импортировать два класса, которым необходимо импортировать AppDelegate?
У меня есть очень специфическая проблема, которую я пытаюсь обвести вокруг себя, и я знаю, что это связано с чем-то, что связано с этим, но я не уверен, что. Поэтому я надеюсь, что если я выясню, как я должен обращаться с таким импортом, и сортировать все остальное, и надеюсь, что это решает мою проблему. Поэтому, чтобы выразить это более конкретно:
У меня есть ClassA.h, ClassB.h и ClassC.h. У всех есть #import "AppDelegate.h" . Когда мне нужно использовать #import "ClassB.h" в ClassA, я удаляю строку #import "AppDelegate.h" из ClassA. Все работает плавно. Но что произойдет, если мне также понадобится #import "ClassC.h" в ClassA, но ClassB и ClassC NEED имеют #import "AppDelegate.h" ?
EDIT:
Я попробовал точный сценарий, описанный выше в чистом проекте, и он построил отлично, так что в игре есть что-то еще. Но я могу с уверенностью сказать, что, когда эта проблема возникла ранее с этим проектом, это было дублированное определение интерфейса AppDelegate, и когда я удалил строку #import "AppDelegate.h" , ошибка исчезла, и я все еще имел доступ к методам и перечислениям AppDelegate.h через другие импортированные файлы.
Ответы
Ответ 1
Лучшая профилактика и лечение для этого - следовать некоторым рекомендациям по импорту из файла заголовка. Как правило, никогда не импортируйте из заголовка Objective-C, за исключением случаев:
- Вам нужно расширить класс, объявленный в другом заголовке.
- Вам необходимо объявить соответствие протоколу, объявленному в другом
заголовок.
- Вам нужно обратиться к неклассическому, не-протокольному типу, определенному в другом заголовке в общедоступных методах и/или свойствах. Чтобы ссылаться на протоколы и классы, переадресовывайте их с помощью
@class
или @protocol
, например @class ClassFromOtherHeader;
Все остальные #import
должны идти в вашей реализации. Моя рекомендация - перенести все ваши выражения #import
из заголовков и в файлы реализации в соответствии с этими правилами. Начните с файлов, которые, по вашему мнению, лежат в основе проблемы и перемещаются наружу. Это устранит вашу проблему и даст вам дополнительное преимущество более четкого кода и более быстрое время сборки.
Ответ 2
Для меня ни один из вышеперечисленных ответов не помогал, и не ответил ли ответ здесь.
Для меня исправлено закрытие Xcode, переход к ~/Library/Developer/Xcode/DerivedData и удаление всех полученных данных, связанных с этим проектом. После этого я снова открыл проект, и он работал нормально.
Надеюсь, что это поможет кому-то!
Ответ 3
В моем случае ни одно из упомянутых решений не устранило проблему. Xcode сообщал о дублированном интерфейсе для класса I, переписанного в Swift. Так или иначе, он продолжал втягивать заголовочный файл Objective-C для класса, на который прямо не ссылалось в проекте.
Я открыл терминал, cd
в каталоге проекта, а затем выполнил следующие действия для отслеживания любых файлов, которые включали заголовок класса:
grep -nr ProblemClassName.h .
Оказалось, что заголовок моста включает устаревший файл, который даже не упоминался в навигаторе проекта. Это, в свою очередь, было импортирование файлов заголовков, на которые ссылается ошибка Xcode, которые также не были включены в навигатор проекта Xcode. Теперь я знаю, что не полагаюсь только на навигатор проектов Xcode для файлов, на которые ссылается ошибка.
tl; dr Дважды проверьте заголовок моста, чтобы убедиться, что все импортированные там файлы должны быть там и не импортировать заголовки, которые в свою очередь импортируют заголовки проблем.
Ответ 4
Я обнаружил, что проект имеет подпроект и вместо ссылки на включения в подпроект с соответствующим синтаксисом:
#import <SubProject/Filename.h>
Он непосредственно импортировал их
#import <Filename.h>
Это было возможно только потому, что путь подпроекта был включен в "пути поиска заголовка" основного проекта - это неправильный способ ведения бизнеса. Поэтому я удалил его оттуда.
Подпроект должен скопировать необходимые включенные файлы в раздел "фазы сборки - скопировать файлы" (который уже происходил на самом деле), и следует использовать надлежащую форму импорта, которая использует синтаксис Subproject/Filename.h.
Ответ 5
Fwiw Я начал получать это, казалось бы, в случайном порядке - для меня исправить было сделать Product->Clean
, и он волшебным образом ушел.
Ответ 6
Для меня я забыл включить скобки в определение интерфейса в файле m.