Макрос препроцессора 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.
Ответы
Ответ 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. Так что не с предварительно скомпилированным вообще