Сбой универсального приложения для iOS на iPhone / iTouch 3.1.3 из-за UIPopoverController - PullRequest
2 голосов
/ 21 октября 2010

Я только что обновил свое приложение, чтобы оно стало универсальным. При этом я добавил поддержку UIPopoverController в определенном месте. Теперь приложение, похоже, дает сбой на устройствах 3.1.3 iPhone / iTouch:

OS Version:      iPhone OS 3.1.3 (7E18)
Report Version:  104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x00000001, 0xe7ffdefe
Crashed Thread:  0

Dyld Error Message:
  Symbol not found: _OBJC_CLASS_$_UIPopoverController

Чего я не понимаю, так это того, что я пытаюсь вызвать UIPopoverController только в том случае, если аппаратным обеспечением является iPad:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:btc];
    CGSize popoverSize = { 300.0, 500.0 };
    popover.delegate = self;
    popover.popoverContentSize = popoverSize;
    self.bmPopover = popover;
    [popover release];

    [self.bmPopover presentPopoverFromBarButtonItem:self.bmBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
    [self presentModalViewController:nav animated:YES];
}

У меня есть iVar и объявлено свойство типа UIPopoverController, но я не ожидал, что это вызовет проблему во время выполнения, если я на самом деле не пытаюсь вызывать методы в классе.

Что я должен сделать, чтобы система не пыталась связываться с UIPopoverController во время выполнения, когда это не поддерживается?

Ответы [ 5 ]

5 голосов
/ 21 октября 2010

Для универсального приложения вы должны не только проверить, является ли это ipad или этот класс существует, но вы должны связать UIKit как Слабая ссылка, а не по умолчанию (сильный), чтобы сделать это:

  1. добраться доИнформация о цели
  2. выберите общие
  3. в связанных библиотеках. Измените UIKit, необходимый для UIKit, слабый

Получайте удовольствие от создания универсальных приложений:]

1 голос
/ 21 октября 2010

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

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    Class UIPopoverControllerClass = NSClassFromString(@"UIPopoverController");
    if (UIPopoverControllerClass != nil) {
        UIPopoverController *popover = [[UIPopoverControllerClass alloc] initWithContentViewController:btc];
        CGSize popoverSize = { 300.0, 500.0 };
        popover.delegate = self;
        popover.popoverContentSize = popoverSize;
        self.bmPopover = popover;
        [popover release];

        [self.bmPopover presentPopoverFromBarButtonItem:self.bmBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
} else {
    [self presentModalViewController:nav animated:YES];
}

Кроме того, вы можете использовать слабую связь с платформой UIKit, что также решит проблему.Я предпочитаю решение кода, поскольку оно более безопасно.

0 голосов
/ 22 октября 2010

Мне показалось полезным добавить это, чтобы я мог использовать UI_USER_INTERFACE_IDIOM () в системах до 3.2.

#ifndef __IPHONE_3_2    // if iPhoneOS is 3.2 or greater then __IPHONE_3_2 will be defined

typedef enum {
    UIUserInterfaceIdiomPhone,           // iPhone and iPod touch style UI
    UIUserInterfaceIdiomPad,             // iPad style UI
} UIUserInterfaceIdiom;

#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone

#endif // ifndef __IPHONE_3_2
0 голосов
/ 21 октября 2010

Вам нужно остановить ошибки компилятора, ссылаясь на класс из строки. Это должно использоваться в тандеме с UI_USER_INTERFACE_IDIOM () и будет компилироваться в SDK, который не знает о UIPopoverController. Вот пример:

Class popClass = NSClassFromString(@"UIPopoverController");
if(popClass) {
    id infoPop = [[popClass alloc] initWithContentViewController:popViewController];
    [infoPop presentPopoverFromRect:CGRectMake(20, 70, 10, 10) inView:self.view permittedArrowDirections:4 animated:YES];
}
0 голосов
/ 21 октября 2010

Простой ответ:

В вашем проекте XCode, выберите значок проекта верхнего уровня.Сделайте Get Info , перейдите на панель BUILD .установите Конфигурации на Все конфигурации , установите Показать: на ** Все настройки **

Установите Целевой показатель для iOS * до iOS 3.1.

Перекомпилируйте.В вашей программе происходит сбой, поскольку минимальная ОС установлена ​​слишком высоко, поэтому загрузчик не может разрешить символ UIPopoverController .Изменения, которые я только что провел, делают этот символ слабым: он разрешится в NULL, но по крайней мере ваша программа загрузится.


Загружаете ли вы файл NIB, который неявно создает UIPopoverController?Это еще один способ разбиться.

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