Условно скрыть код из компилятора

Итак, вот проблема. Я должен скоро выпустить обновление для iOS, которое рассмотрит некоторые проблемы в iOS 7. Для этого мне нужно использовать некоторые конкретные функции/типы iOS 7. Я абсолютно уверен, что код iOS 7 будет выполнен только на iOS 7 и резерв на другой код для предварительного iOS 7. Конечно, мне не разрешено отправлять текущую бета-версию Xcode, поэтому я пытаюсь скомпилировать с текущей версией Xcode. Однако я не могу найти способ отключить это конкретное предупреждение:

Use of undeclared identifier '<Redacted>'.

Кто-нибудь знает, как отключить это предупреждение, используя #pragma. Я пробовал кучу разных, включая

-w, -Weverthing, -Wall

но ничего не работает.

UPDATE Ответ: Вы не можете, конечно, потому, что компилятор не может скомпилировать идентификатор, о котором он ничего не знает. Мои решения состояли в том, чтобы просто создать #define:

#define <redacted> 1

ОБНОВЛЕНИЕ 2 Ответ ниже на самом деле сделал это намного проще. Я уже создал #define Xcode5Code(code, alt), что позволило мне выполнить блоки кода условно. Изменив его с помощью решения @maddy:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
    #define Xcode5Code(code, alt) code
#else
    #define Xcode5Code(code, alt) alt
#endif

Это позволяет мне легко скрыть блоки кода из компилятора, используя:

Xcode5Code({
    //Code to be execute only with Xcode 5
}, {
    //code to be executed in previous versions of Xcode
})

Основное преимущество использования #define Xcode5Code заключается в том, что Xcode автоматически завершит его для вас, что намного проще, чем использование полного #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000, который Xcode не будет автоматически завершен.

На самом деле это не будет отличать устройства iOS 7 и pre iOS 7. Это только отличает, какую версию iOS можно использовать для текущего Xcode. Чтобы различать версии iOS-устройств, я использую:

NSUInteger DeviceSystemMajorVersion(void) {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _deviceSystemMajorVersion = [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
    });
    return _deviceSystemMajorVersion;
}

Вышеприведенный код Apple, кстати. Чтобы немного помахать вокруг NDA, я скажу, что это помогает выложить представление корневого контроллера, потому что это зависит как от версии Xcode, которую вы используете, так и от версии iOS, которая находится на устройстве. И если вы пытаетесь управлять бета-версией, а также производственным кодом, это может многое помочь. После того, как вы сможете отправлять приложения с помощью Xcode 5, #define Xcode5Code больше не понадобится.

Ответы

Ответ 1

Если вы хотите скомпилировать свое приложение с двумя разностными версиями Xcode или двух разных базовых настроек SDK, вам следует использовать директивы компилятора:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 // iOS 7.0 supported
    // iOS 7 code here
#else
    // Pre-iOS 7 code here
#endif

Не используйте это для проверок времени выполнения. Это решение должно использоваться только тогда, когда вы должны скомпилировать свой код с двумя разными версиями. Например, вы добавили код iOS 7, но вам все равно нужно скомпилировать код с Xcode 4.6. Использование директив компиляции позволяет "скрыть" код iOS 7 от компилятора с использованием старого базового SDK.

См. "Руководство по совместимости SDK" в документах для получения дополнительных сведений об этом и правильных проверках времени выполнения.