Ошибка компиляции универсального приложения iPhone / iPad для тестирования iPhone - PullRequest
30 голосов
/ 12 апреля 2010

Я написал универсальное приложение для iPhone и iPad, которое отлично работает в симуляторе iPad на XCode, но теперь я хотел бы проверить функциональность iPhone. Кажется, я не могу запустить симулятор iPhone с этим кодом, так как он всегда по умолчанию - iPad?

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

dyld: Symbol not found: _OBJC_CLASS_$_UISplitViewController
  Referenced from: /var/mobile/Applications/9770ACFA-0B88-41D4-AF56-77B66B324640/Test.app/Test
  Expected in: /System/Library/Frameworks/UIKit.framework/UIKit in /var/mobile/Applications/9770ACFA-0B88-41D4-AF56-77B66B324640/Test.app/TEST

Поскольку приложение построено программно, а не с использованием XIB, я разделил логику двух устройств, используя следующие строки в методе main.m:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate_Pad");
}
else
{
    retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate_Phone");
}

С этого момента они используют разные AppDelegates, и я проверил мои заголовки, чтобы убедиться, что UISplitView никогда не используется и не импортируется через логику телефона.

Как мне избежать этой ошибки и есть ли лучший способ разделить универсальные логические пути в этом программно созданном приложении?

Ответы [ 3 ]

66 голосов
/ 12 апреля 2010

Эта ошибка вызвана тем, что вы не установили слабую связь с UIKit-фреймворком. Инфраструктура UIKit в iPhone OS 3.2 добавила UISplitViewController, и если вы свяжете его как обычно, ваше приложение предположит, что эти символы существуют в 3.0, а их нет.

Чтобы создать слабую ссылку на фреймворк, найдите цель приложения в Xcode, проверьте ее и перейдите на вкладку Общие. Внизу этой вкладки должен быть список фреймворков со столбцом для Type. Измените Тип для UIKit с Обязательного на Слабый и пересоберите свое приложение. Это должно позаботиться об ошибках во время выполнения.

Ваша условная логика здорова, но я склонен делиться делегатом приложения и делать макет для конкретного интерфейса дальше.

(Обновление: 21.12.2011) Начиная с iOS 4.2, вам больше не нужно использовать слабые фреймворки для предотвращения подобных ошибок. Как описывает Марко Армент , если вы собираете с iOS 4.2 или более поздней версией и ориентируетесь на iPhone OS 3.1+, отдельные классы теперь слабо связаны и должны иметь свой метод +class, возвращающий nil, если класс делает не существует в текущей версии ОС.

4 голосов
/ 12 апреля 2010

У меня была очень похожая ошибка, и это сводило меня с ума! :-) Искал часами и не мог разобраться ...

Как вы сказали, все было нормально при запуске в iPad Simulator, но при попытке протестировать приложение на iPhone с iPhone OS 3.1.2 оно даже не запустилось бы, а зависло со следующим сообщением об ошибке:

mi_cmd_stack_list_frames недостаточно кадров в стеке

Проверив почти каждую строку кода, я понял, что проблема заключается в выделении 3.2 классов, таких как UIPopoverController или UISplitViewController (уже внутри разветвленного кода для iPad).

Так что вместо i.e.:

infoPopover = [[UIPopoverController alloc] initWithContentViewController: infoNavController];

я бы написал

infoPopover = [[NSClassFromString (@ "UIPopoverController") alloc] initWithContentViewController: infoNavController];

и это решило мою проблему! (Отладка может быть очень сложной, если сообщение об ошибке не дает вам подсказки о том, где ошибка может быть найдена ...)

0 голосов
/ 17 августа 2017

Xcode 8.3, iPad 2 (без сетчатки), код Swift 3

Что помогло мне:

  • перезагрузите Xcode
  • сделать 'Продукт -> Очистить' Сдвиг Команда К
  • пересобрать проект
...