iPhone проверяет постоянную во время выполнения в универсальном приложении - PullRequest
5 голосов
/ 28 апреля 2010

Я делаю универсальное приложение для iPad / iPhone, которое может использовать выходной разъем VGA для iPad, чтобы отобразить содержимое приложения на внешнем экране. Тем не менее, iPhone не имеет этой функциональности. учитывая следующий код,

#ifdef UI_USER_INTERFACE_IDIOM  
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    NSLog(@"this code should not execute on iphone");
[[NSNotificationCenter defaultCenter] addObserver:self
         selector:@selector(screenInfoNotificationReceieved:) 
          name:UIScreenDidConnectNotification
           object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
         selector:@selector(screenInfoNotificationReceieved:) 
          name:UIScreenDidDisconnectNotification
           object:nil];
}
#endif

Я получаю эту ошибку на телефоне при запуске (отлично работает в ipad) "dyld: символ не найден: _UIScreenDidConnectNotification"

предположительно, потому что UIScreenDidConnectNotification 'еще не существует в 3.13. Как я могу проверить это во время выполнения?

ОБНОВЛЕНО добавлены операторы ifdef для проверки интерфейса ipad, но с тем же результатом!

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

Ответы [ 4 ]

3 голосов
/ 28 апреля 2010

Попробуйте слабую ссылку UIKit. Добавьте в ваши другие ссылки флаги:

-all_load -ObjC -weak_framework UIKit

Если вы нацелены на устройства до 3.1, но ссылаетесь на класс, который существует только в 3.2, вы не можете ссылаться на них по символу, вы должны использовать NSClassFromString. Но есть случаи, когда это невозможно, например, если вы подкласса такого класса (скажем, UIPopoverController). В этих случаях вы должны использовать слабую ссылку UIKit. При слабом связывании фреймворка динамический загрузчик пытается разрешить все символы при запуске, в случае сбоя устанавливается значение NULL.

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

У слабой связи есть и обратная сторона. Так как он должен делать это при запуске, динамически, время запуска принимает удар. Вам придется проверить, не слишком ли это медленно для вас.

Еще один способ слабого связывания фрейма: выполните «Get Info» для своей цели и на вкладке General вы увидите список фреймворков. Измените тип для UIKit на Слабый.

Кстати, использование #ifdef для проверки не работает, потому что #ifdef являются конструкциями времени компиляции, поэтому UI_USER_INTERFACE_IDIOM всегда будет определяться, потому что вы строите с использованием 3.2 SDK

1 голос
/ 25 февраля 2011

Из ответа Эльфреда на связанный вопрос: Как проверить наличие константы при создании универсального двоичного файла iPhone

if (NULL != &UIBackgroundTaskInvalid) {
   //do multitasking stuff here
} else {
   // don't do multitasking stuff here.
}
0 голосов
/ 10 июня 2010

Еще один способ слабого связывания фрейма: выполните «Get Info» для своей цели и на вкладке General вы увидите список фреймворков. Измените тип для UIKit на Слабый.

Это помогло мне решить проблему «Символ не найден: _UIScreenDidConnectNotification» на iPhone во время выполнения.

0 голосов
/ 28 апреля 2010

Следуйте разделу «Программно определяемое устройство» на http://iphonedevelopment.blogspot.com/2010/04/converting-iphone-apps-to-universal.html

плюс

#ifndef __IPHONE_3_2 // if iPhoneOS is 3.2 or greater then __IPHONE_3_2 will be defined
  typedef enum { // provided by noblemaster ]:-|
    UIUserInterfaceIdiomPhone, // iPhone and iPod touch style UI
    UIUserInterfaceIdiomPad, // iPad style UI
  } UIUserInterfaceIdiom;
  #define UI_USER_INTERFACE_IDIOM() (([[UIDevice currentDevice].model rangeOfString:@"iPad"].location != NSNotFound) ? UIUserInterfaceIdiomPad : UIUserInterfaceIdiomPhone)
#endif // ifndef __IPHONE_3_2 

в разделе комментариев.

...