Какую условную компиляцию использовать для переключения между Mac и iPhone определенного кода?

Я работаю над проектом, который включает приложение Mac и приложение для iPad тот код доли. То, как я могу использовать условную компиляцию, переключается для исключения определенного для Mac кода из проекта iPhone и наоборот? Я заметил это TARGET_OS_IPHONE и TARGET_OS_MAC и 1, и таким образом, они оба всегда верны. Есть ли другой переключатель, который я могу использовать, который только возвратит true при компиляции для определенной цели?

По большей части я заставил файлы сотрудничать путем перемещения #include <UIKit/UIKit.h> и #include <Cocoa/Cocoa.h> в заголовки перед компиляцией для этих двух проектов. Я совместно использую модели и некоторый служебный код, который выбирает данные из каналов RSS и Evernote.

В частности, [NSData dataWithContentsOfURL:options:error:] функция берет другую константу для параметра iOS 3.2 опций и ранее и Mac OS 10.5 и ранее, чем это делает для iOS 4 и Mac OS 10.6. Условное выражение, которое я использую:

#if (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2)) || (TARGET_OS_MAC && (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5))

Это, кажется, работает, но я хочу удостовериться, что это является пуленепробиваемым. Мое понимание - то, что, если версия Mac установлена на 10,6, но версия iOS установлена на 3,2, она будет все еще использовать новые константы, даже если она скомпилирует для iOS 3.2, который кажется неправильным.

Заранее спасибо за любую справку!

39
задан Jose Ibanez 5 July 2010 в 17:53
поделиться

2 ответа

Вы ошиблись в своих наблюдениях. :)

TARGET_OS_MAC будет 1 при создании приложения для Mac или iPhone. Вы правы, это совершенно бесполезно для такого рода вещей.

Однако TARGET_OS_IPHONE равен 0 при создании приложения Mac. Я постоянно использую TARGET_OS_IPHONE в своих заголовках для этой цели.

Вот так:

#if TARGET_OS_IPHONE
// iOS code
#else
// OSX code
#endif

Вот отличный график: http://sealiesoftware.com/blog/archive/2010/8/16/TargetConditionalsh.html

66
ответ дан 27 November 2019 в 02:24
поделиться

"Правильнее всего просто использовать новые константы, потому что если вы посмотрите на заголовок, то увидите, что они объявлены эквивалентными старым в перечислении, что означает, что новые константы будут работать даже на старых релизах (обе константы компилируются в одно и то же, а поскольку перечисления компилируются в приложение, они не могут измениться без нарушения бинарной совместимости). Единственная причина не делать этого - если вам нужно продолжать сборку на старых SDK (это отличается от поддержки старых релизов, которую можно осуществлять при компиляции на новых SDK).

Если вы действительно хотите использовать разные флаги в зависимости от версии ОС (потому что новая версия действительно добавила новую функциональность, а не просто переименовала константу), то есть две разумные вещи, которые вы можете сделать, и ни одна из которых не достигается приведенным выше макросом:

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

    #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
     NSDataReadingOptions options = NSDataReadingMapped;
    #else
     NSDataReadingOptions options = NSMappedRead;
    #end
    
  2. Условно используйте только новые значения в сборках, которые могут работать только с новыми версиями, и компилируйте код для определения флагов во время выполнения для сборок, поддерживающих обе версии:

    #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
     NSDataReadingOptions options = NSDataReadingMapped;
    #else
     Опции NSDataReadingOptions;
     if ([[UIDevice currentDevice] systemVersion] compare:@"4.0"] != NSOrderedAscending) {
     options = NSDataReadingMapped;
     } else {
     options = NSMappedRead;
     }
    #end
    

Обратите внимание, что если бы вы действительно часто выполняли это сравнение, вы бы захотели сохранить результат [[UIDevice currentDevice] systemVersion] compare:@"4.0"] где-нибудь. Также обычно требуется явная проверка на наличие функций с помощью таких вещей, как слабая связь, вместо сравнения версий, но это не вариант для перечислений.

8
ответ дан 27 November 2019 в 02:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: