Быстрая альтернатива для диагностики #pragma clang

Проблема

Недавно я встретил предупреждение в сторонней утилите (WEPopover) в этом фрагменте кода:

_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

Это вызвало следующее предупреждение:

warning: 'contentSizeForViewInPopover' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations]
            _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

Одно временное исправление для этого в Objective-C - использовать диагностику pragma clang, чтобы заставить замолчать ошибку (я позволю автору кода разобраться с истинным исправлением). Поэтому я пересмотрел код следующим образом:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
            _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

#pragma clang diagnostic pop

Вопрос

Это работает отлично, но это заставило меня подумать над тем, что, если какая-либо альтернатива существует там, где нужно было бы отключить подобное ложное положительное предупреждение при кодировании в Swift?

Вопросы

Я заметил, что я могу деактивировать такой проект предупреждений в широком масштабе (используя настройки Xcode), но я хочу рассмотреть встроенную проблему, как указано выше. Я также рассмотрел возможность добавления #define в файл .bridging-header.h в моем проекте Swift и каким-то образом использовать его; однако я ищу быстрое решение этой проблемы. Я понимаю, что прагма больше недоступна, и я искал SO и нашел похожие, но не повторяющиеся вопросы.

ОБНОВЛЕНО РЕШЕНИЕ: Swift 2.0

В представленном ответе рассматривается мое беспокойство по поводу встроенных предупреждений. Команда доступности должна позволять избегать таких проблем, поскольку во время компиляции будет предупреждаться.

В книге Apple Swift говорится:

"Вы используете условие доступности в выражении if или guard для условно выполнить блок кода, в зависимости от того, являются ли интерфейсы API вы хотите использовать, доступны во время выполнения. Компилятор использует информацию из условия доступности, когда она проверяет, что API-интерфейсы в этом" блоке кода".

 if #available(iOS 9, OSX 10.10, *) {
 // Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X 
 } else {
 // Fall back to earlier iOS and OS X APIs 
 }

"

Отрывок из: Apple Inc. "Быстрый язык программирования (Swift 2 Preerelease)". интерактивные книги. https://itun.es/us/k5SW7.l"

Можно даже использовать инструкцию охраны в сочетании с доступностью для выхода из области раньше, если только не будут выполнены доступные условия.

guard #available(iOS 8.0, OSX 10.10, *) else { return }

Отрывок из: Apple Inc. "Использование Swift с Cocoa и Objective-C (Swift 2 Prerelease)." интерактивные книги. https://itun.es/us/utTW7.l

Кроме того, мои связанные с этим проблемы при обработке макросов рассматриваются, как указано ниже. Имея в виду, что у Swift нет препроцессора, эти инструменты выглядят как способ.

" Простые макросы

Если вы обычно использовали директиву #define для определите примитивную константу в C и Objective-C, в Swift вы используете глобальная константа. Например, определение константы #define FADE_ANIMATION_DURATION 0.35 может быть лучше выражено в Swift с let FADE_ANIMATION_DURATION = 0,35. Потому что простые константные макросы сопоставить непосредственно с глобальными переменными Swift, компилятор автоматически импортирует простые макросы, определенные в исходных файлах C и Objective-C.

Отрывок из: Apple Inc." Использование Swift с Cocoa и Objective-C(Swift 2 Preerelease). "IBooks. https://itun.es/us/utTW7.l

" Сложные макросы

Сложные макросы используются в C и Objective-C, но не имеют аналогов в Свифт. Сложные макросы - это макросы, которые не определяют константы, включая скобки, функциональные макросы. Вы используете сложные макросы в C и Objective-C, чтобы избежать ограничений проверки типов или избежать переименование большого количества кода шаблона. Однако макросы могут отладки и реорганизации. В Swift вы можете использовать функции и дженериков для достижения тех же результатов без каких-либо компромиссов. Поэтому "сложные макросы, которые находятся в источнике C и Objective-Cфайлы не доступны для вашего кода Swift."

Отрывок из: Apple Inc. "Использование Swift с Cocoa и Objective-C (Swift 2 Prerelease)." интерактивные книги. https://itun.es/us/utTW7.l

Разработчик API сможет отмечать доступность функций в Swift, используя:

available(iOS 8.0, OSX 10.10, *)
func useShinyNewFeature() {
    // ...
}

Отрывок из: Apple Inc. "Использование Swift с Cocoa и Objective-C (Swift 2 Prerelease)." интерактивные книги. https://itun.es/us/utTW7.l

Добавление этих маркеров в функции, переписанные для Swift, похоже, является хорошим способом поддерживать обратную совместимость для Framework. Охранная/доступная комбинация позволит пользователям этих фреймворков при необходимости корректировать логику. Который с легкостью справляется с обработкой как встроенных предупреждений, так и ошибок API, и макросов в целом.

Ответ 1

Начиная с версии 2.0 (в настоящее время в бета-версии на момент написания этой статьи), Swift по-прежнему не включает препроцессор и не хочет менять его в ближайшее время (если вообще). Благоприятные способности, которые допускают препроцессоры, встроены в язык по-разному (я не буду рассматривать их все здесь, см. Документы) и функции уровня времени компиляции.

Есть две особенности, которые я хочу упомянуть (один старый, один новый), который может быть тем, что вы ищете:

  • Условная компиляция. Как описано в С помощью Swift с Cocoa и Objective-C вы можете реализовать условные компиляции, которые позволяют компилировать код только для определенных операционных систем или архитектур процессоров. Если выглядит примерно так:

enter image description here

  1. Проверка доступности API. Как описано в Язык Swift Programming, теперь вы можете проверить наличие API основанный на платформе и версии ОС. Это позволит вам использовать новый API, позволяя вам работать, когда эта функция недоступна на более старой (или другой) платформе или ОС. Вы можете использовать это для sub в альтернативной реализации или представить объяснение пользователю. Если выглядит примерно так:

enter image description here

Эти инструменты (наряду со многими другими встроенными в язык) должны позволить разработчику заменить макросы Objective-C и C препроцессора. Лично я считаю, что это огромное улучшение.