Универсальная ошибка компиляции приложения для iPhone/iPad для тестирования iPhone
Я написал универсальное приложение для 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, я разделил 2 логики устройств, используя следующие строки в методе 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 никогда не используется и не импортируется через логику телефона.
Как избежать этой ошибки и есть ли лучший способ разделить универсальные логические пути в этом программно-созданном приложении?
Ответы
Ответ 1
Эта ошибка запускается, потому что вы не использовали слабую связь с базой UIKit. Рамка UIKit в iPhone OS 3.2 добавила UISplitViewController, и если вы свяжете ее как обычно, ваше приложение будет считать, что эти символы существуют в версии 3.0, где они этого не делают.
Чтобы слабая ссылка на фреймворк, найдите цель приложения в Xcode, проверьте его и перейдите на вкладку "Общие". В нижней части этой вкладки должен быть список фреймворков с столбцом для Type. Измените тип для UIKit от Required to Weak и перестройте приложение. Это должно заботиться о ошибках времени выполнения.
Ваша условная логика звучит, но я имею тенденцию делиться делегатом приложения и выполнять макет интерфейса, расположенный ниже строки.
(Обновление: 12/21/2011). Начиная с iOS 4.2 вам больше не понадобятся слабые структуры ссылок для предотвращения таких ошибок. Как Марко Армент описывает, если вы создаете с iOS 4.2 или новее и нацеливаетесь на iPhone OS 3.1+, отдельные классы теперь слабо связаны и должны иметь их метод +class
возвращает nil
, если класс не существует в текущей версии ОС.
Ответ 2
У меня была очень похожая ошибка, и это сводило меня с ума!:-) Поиск в течение нескольких часов и не мог понять это...
Как вы сказали, все было в порядке, когда работали в 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];
и это решило мою проблему! (Отладка может быть настолько сложной, если сообщение об ошибке не дает вам понять, где можно найти ошибку...)
Ответ 3
Xcode 8.3, iPad 2 (не сетчатка), код Swift 3
Что мне помогло:
- перезапустить Xcode
- сделать "Продукт → Очистить" Shift Command K
- перестроить проект