Подтвердить что ты не робот

Макрос препроцессора Xcode, чтобы проверить, поддерживает ли Base SDK >= iOS 7.0

Есть ли какой-либо макрос препроцессора для компиляции определенных частей кода, только если базовый SDK равен 7.0 или выше? Определенная константа "__IPHONE_7_0", по-видимому, связана с целью разработки iOS (а не с базовым SDK).

Я использую XCode 5 с установленными iOS 7 и iOS 6.1.

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

Пример:

if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [_tableView setSeparatorInset:UIEdgeInsetsZero];
}

Этот фрагмент кода не компилируется с SDK базы данных iOS 6.1, поскольку он жалуется на то, что setSeparatorInset не определен для UITableView. Поэтому я хотел бы включить этот фрагмент кода в директиву препроцессора, условно на базовый SDK.

4b9b3361

Ответ 1

Вы должны прочитать Руководство по совместимости SDK от Apple , где объясняются все эти методы.

В частности, они рекомендуют использовать макрос __IPHONE_OS_VERSION_MIN_REQUIRED для тестирования с Целью развертывания вашего проекта (минимальная поддерживаемая версия), а для вашего случая используйте макрос __IPHONE_OS_VERSION_MAX_ALLOWED для тестирования базового SDK, используемого для компиляции.


Пример:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
// Only COMPILE this if compiled against BaseSDK iOS7.0 or greater
if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) {
   // Even when compiled with BaseSDK 7, only EXECUTE that if the user uses an
   // OS that support this method (namely if the user is running iOS7 or later,
   // but not for users running iOS6).
   [_tableView setSeparatorInset:UIEdgeInsetsZero];
}
#endif

Важное примечание. Вы должны использовать числовые константы в сравнении, как если бы вы тестировали #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0, например, он не будет работать при использовании SDK 6, так как __IPHONE_7_0 не определяется, таким образом, оценивается как 0 в этом контексте и ваше условие не будет работать должным образом.

Ответ 2

Да, вы можете использовать __IPHONE_7_0 define:

#ifdef __IPHONE_7_0
    if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [_tableView setSeparatorInset:UIEdgeInsetsZero];
    }
#endif

Ответ 3

В соответствии с Apple Doc вы должны использовать NSFoundationVersionNumber, чтобы различать iOS 7 и другие. Вы можете упростить использование следующих макросов:

#define isIOS6 floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1 
#define isIOS7 floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1

а затем в коде do

#ifdef __IPHONE_7_0
    if (isIOS7) {
       // Do additional stuff for iOS 7.
    } 
#endif

Да, вы должны проверить как время компиляции (с #ifdef), так и время выполнения (с isIOS7) таким образом, вы сможете скомпилировать с SDK iOS6, SDK iOS7, а также SDK iOS7 с iOS6 мишени.

ОН! Помните, что вы не можете сделать if (!isIOS7), вам нужно использовать if (isIOS6).

https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/

Ответ 4

Кроме того, вы можете использовать этот макрос

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

e.g if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.1")) {[self doSomething];} else {[self doSomethingElse];}

Ответ 5

Вы не должны тестировать sdk, но для доступности метода/класса IMHO. Так что не с предварительно скомпилированным вообще