Ошибка «Неизвестный класс <MyClass>в файле Interface Builder» во время выполнения - PullRequest
259 голосов
/ 13 ноября 2009

Несмотря на то, что Interface Builder знает о MyClass, я получаю сообщение об ошибке при запуске приложения.

Это происходит, когда MyClass является частью библиотеки, и не происходит, если я компилирую класс непосредственно в целевом приложении.

Ответы [ 46 ]

218 голосов
/ 13 ноября 2009

Несмотря на ошибку « Неизвестный класс MyClass в файле Interface Builder. », напечатанную во время выполнения, эта проблема не имеет ничего общего с Interface Builder, а скорее с компоновщиком, который не связывает класс, потому что нет Код использует его напрямую.

Когда данные .nib (скомпилированные из .xib) загружаются во время выполнения, на ссылку MyClass ссылается строка, но компоновщик не анализирует функциональность кода, а только существование кода, поэтому он не знает, что , Поскольку другие исходные файлы не ссылаются на этот класс, компоновщик оптимизирует его при создании исполняемого файла. Поэтому, когда код Apple пытается загрузить такой класс, он не может найти связанный с ним код и выводит предупреждение.

По умолчанию для целей Objective-C будут установлены -all_load -ObjC флажки по умолчанию, в которых будут храниться все символы. Но я начал с цели C ++ и не имел этого. Тем не менее, я нашел способ обойти это, что делает линкер агрессивным.

Хак, который я изначально использовал, заключался в добавлении пустой статической подпрограммы, например:

+(void)_keepAtLinkTime;

, который ничего не делает, но я бы назвал один раз, например:

int main( int argc, char** argv )
{
   [MyClass _keepAtLinkTime];
   // Your code.
}

Это заставит компоновщик сохранить весь класс, и ошибка исчезнет.

Как указал jlstrecker в комментариях, нам не нужно добавлять метод _keepAtLinkTime. Просто позвоните существующему, например:

   [MyClass class];

делает трюк (если вы производите от NSObject).

Конечно, вы можете позвонить в любое место вашего кода. Я думаю, это может быть даже в недоступном коде. Идея состоит в том, чтобы обмануть компоновщика, заставляя его думать, что MyClass используется где-то, чтобы он не был настолько агрессивным в его оптимизации.

Xcode 6.3.2 и Swift 1.2

Быстрое определение зрения. Обязательно переопределите init(coder aDecoder: NSCoder). Objective-C определение представления контроллера. И перо в грушевом дереве.

Добавьте имя модуля в инспектор деталей Nib, где вы выбираете свой класс.

183 голосов
/ 24 августа 2011

Я исправил это в соответствии с тем, что предложила Лора, но мне не нужно было воссоздавать файлы.

  • Используя XCode 4, в Project Navigator выберите файл .m, который содержит класс, на который он жалуется

  • Перейдите в Вид-> Утилиты-> Показать инспектор файла
    (это покажет Инспектор файлов справа, с информацией этого файла .m)

  • Откройте раздел Target Membership и убедитесь, что ваша цель выбрана для этого .m-файла

Когда я добавил свой файл .m в свой проект, он по какой-то причине не добавил его к цели по умолчанию, и из-за этого я получил ошибку, о которой вы упоминали.

68 голосов
/ 23 мая 2011

Это на самом деле не имеет ничего общего с Interface Builder, здесь происходит то, что символы не загружаются из вашей статической библиотеки Xcode. Чтобы решить эту проблему, вам нужно добавить флаги -all_load -ObjC в ключ Other Linker Flags в настройках сборки проекта (и, возможно, цели).

Поскольку Objective-C генерирует только один символ на класс, мы должны заставить компоновщик загружать члены класса тоже, используя флаг -ObjC, и мы также должны принудительно включить все наши объекты из нашей статической библиотеки, добавив -all_load флаг компоновщика. Если вы пропустите эти флаги рано или поздно, вы столкнетесь с ошибкой unrecognized selector или получите другие исключения, такие как тот, который вы наблюдали здесь.

26 голосов
/ 12 марта 2015

Я столкнулся с этой проблемой сегодня, используя Swift.

Я изменил класс Model.h + Model.m на Model.swift. Этот объект использовался в Интерфейсном Разработчике с class = Model.

Как только я заменил объект, класс больше не мог быть загружен.

Мне нужно было изменить ссылку на класс в IB с:

Class = Model
Module = 

до

Class = Model
Module = <TARGETNAME>

Вы найдете <TARGETNAME> в настройках сборки. Это также имя, которое отображается в созданном вами Swift-заголовке: #import "TARGETNAME-Swift.h"

20 голосов
/ 13 декабря 2012

Перейдите в «ProjectName», щелкните по нему, а затем перейдите на вкладку «Build фазы», ​​а затем нажмите на «источник компиляции», а затем нажмите кнопку «+», появится окно, выберите Файл «MyClass.m» и нажмите «Добавить»,

Постройте проект и запустите его, проблема наверняка будет решена

19 голосов
/ 05 апреля 2011

Это проблема с кешем Xcode4, просто удалите все папки в / Users / your_user / Библиотека / Поддержка приложений / iPhone Simulator / 4.3 / Приложения /

Также, если у вас есть тот же вопрос тестирования на вашем iPhone, удалите старое приложение перед запуском ...

Удачи. Паскуаль

16 голосов
/ 30 ноября 2014

Иногда IBuilder пропускал customModule="AppName" customModuleProvider="target"

Чтобы исправить это, откройте раскадровку в качестве исходного кода и замените эту строку:

<viewController storyboardIdentifier="StoryboardId" id="SomeID" customClass="CustomClass"
sceneMemberID="viewController">

к этому:

<viewController storyboardIdentifier="StoryboardId" id="SomeID" customClass="CustomClass"
 customModule="AppName" customModuleProvider="target" sceneMemberID="viewController">
13 голосов
/ 05 апреля 2017

Мой случай - пытаясь использовать класс из быстрой среды в моем проекте c, я получил эту ошибку. Решением было добавить модуль (swift framework) класса в Interface Builder / Storyboard, как показано ниже. Ничего другого

enter image description here

13 голосов
/ 10 июля 2012

Перейдите в Фазы сборки-> Компилировать исходники и добавьте новые файлы .m.

13 голосов
/ 12 ноября 2013

В моем случае это показывало ошибку для класса, который даже не существовал! Я подозревал, что это было что-то запутанное в файле раскадровки. Если вы не можете распознать файл класса в ошибке, попробуйте это:

1) откройте свой проект в возвышенном или другом хорошем редакторе. Найдите класс, на который вы ссылаетесь. 2) удалить весь бит, который говорит

customClass="UnrecognizedClassName"

3) сохранить его. 4) вернитесь в xcode, очистите проект и попробуйте запустить его сейчас.

работал на меня.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...