Как быстро отключить предупреждение

98

У меня есть фрагмент кода, который генерирует множество предупреждений (устаревший API)

Используя clang *, я мог бы сделать

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

Однако это не работает быстро.

Как это сделать быстро?

Примечание. Я не хочу отключать предупреждение глобально или даже для всего файла, а просто отключу конкретное предупреждение в определенной части исходного кода.

Изменить: похоже, моя заметка была недостаточно ясной: я НЕ хочу условной компиляции (это предлагаемый ответ предполагаемого дубликата). Я просто хочу отключить предупреждение БЕЗ использования новых API.

Antzi
источник
4
Это не дубликат. Другой вопрос не дает ответа на эту проблему.
Claus Jørgensen
@ ClausJørgensen, каким образом он не может решить эту проблему? Нет другого способа, как указано в ответах на связанный вопрос. Просто условная компиляция или новый #availableмакрос, где разработчик должен использовать новые методы и откатиться к старым, если новые недоступны.
zrzka
@robertvojta Нет, поскольку в ответах фактически не говорится, что нет других способов отключить предупреждение.
Claus Jørgensen
2
Это не обман. Как насчет ситуации, когда вы получаете предупреждение об отсутствии инициализатора?
NSTJ

Ответы:

162

По состоянию на 2020 год, Xcode 12.0, единодушное мнение заключается в том, что этого невозможно достичь.

Я обновлю / отредактирую этот ответ, если Apple добавит эту функцию.

Поместите его в свой список желаний на WWDC 2021!

Antzi
источник
22
Блин, это облом. Иногда это выходит из-под контроля . Это, мягко говоря, раздражает.
Isuru
2
Я хочу миллион раз проголосовать за этот ответ, но он отвечает на вопрос довольно хорошо, так что +1 :-)
deadbeef
3
@Isuru В этот момент я достаточно разозлился, чтобы просто все это перестроить. Угадайте, что предупреждения сработали
Сирены
1
@Isuru Большинство из них следует исправить, а не игнорировать.
Кевин
3
Так обидно! Спасибо, что обновили этот ответ.
Дэн
48

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

Допустим, у вас есть метод getLatestImage()класса, Fooкоторый использует устаревшие методы / классы.

Используйте, @availableкак описал Даниэль Торп, чтобы отключить все предупреждения внутри метода:

@available(iOS, deprecated: 9.0)
func getLatestImage() -> UIImage? {
    ...
}

Теперь вы хотите вызвать метод getLatestImage()без предупреждения об устаревании. Вы можете добиться этого, сначала определив протокол и расширение:

private protocol GetLatestImage {
    func getLatestImage() -> UIImage?
}
extension Foo: GetLatestImage {}

А затем вызовите метод без предупреждения об устаревании (если fooэто экземпляр Foo):

(foo as GetLatestImage).getLatestImage() // no deprecation warning

В результате у вас есть код Swift, который использует устаревший API без каких-либо предупреждений об устаревании.

Таммо Фризе
источник
Такой умный. Вид зла? :) Но так хорошо. Отлично подходит для такого случая использования, как подавление предупреждений о продолжающемся использовании некоторых аспектов инфраструктуры AddressBook, которые устарели, но у которых есть замена, на самом деле еще не обеспечивает всех необходимых функций. Спасибо.
Дункан Бэббидж
4
Если это сработает, я пришлю тебе шесть упаковок твоего любимого напитка. у вас выдающийся ум, сэр, спасибо.
Джон
@John Спасибо за добрые слова! Он действительно работает, мне пришлось его придумать, поскольку мы рассматриваем предупреждения как ошибки в нашей кодовой базе, и в одном разделе все еще используется устаревшая библиотека.
Tammo Freese
1
@ Джон, ты послал ему шесть пачек? : P Это круто. Гений. Спасибо.
Баран Эмре
Вы злой гений.
Krypt
38

Фактически, вы можете подавить эти предупреждения, используя @availableво включающую логическую структуру (то есть функцию / тип).

Например, предположим, что у вас есть код, использующий структуру AddressBook, но вы строите его на базе iOS 9.

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus {
    return ABAddressBookGetAuthorizationStatus()
}

Начиная с Xcode 7.0.1 это предотвратит отображение встроенных предупреждений.

Дэниел Торп
источник
6
Да, но вы увидите такое же предупреждение, когда вызовете свой addressBookStatus()... который вы помечаете как устаревший.
Валентин Шергин
3
Про совет: если вы хотите , чтобы заставить замолчать его для всего класса просто хлопнуть этот щенок вверх выше вашего класс заявления (например: class ViewController: UIViewController)
Сирены
2
@Sirens Тогда вы будете видеть это предупреждение каждый раз, когда вызываете этот класс ☹️ (по крайней мере, с Xcode 8)
Александр Васенин
Кому-нибудь удалось отключить все устаревшие предупреждения с помощью этого исправления? Мне удалось уменьшить их количество до одного , но я не вижу способа избавиться от последнего. Какие-либо предложения?
Александр Васенин
1
Итак, как использовать это, чтобы отключить предупреждение «приведение из CGFloat.NativeType (также известного как« Double ») к несвязанному типу« Float »всегда не работает», когда я выполняю команду if CGFloat(0).native is Float { … }? Ответ: Я не использую это, потому что вы не ответили на вопрос.
Слипп Д. Томпсон
1

Хотя на данный момент нет способа отключить предупреждения об устаревании в Swift, технически вы можете сделать это для определенного символа, отредактировав файл заголовка.

  • Скопируйте устаревшее имя символа
  • Выбрать File>Open Quickly
  • Вставьте символ и нажмите Enter

    Убедитесь, что значок Swift отключен в поле «Открыть быстро».

  • Выбрать File>Show in Finder

  • Измените права доступа к файлу, чтобы разрешить редактирование при необходимости
  • Отредактируйте устаревшие макросы для символа. См. Окружающие API для справки. Например, заменить:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

с участием

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Теперь есть одно менее отвлекающее предупреждение, с которым вы ничего не можете поделать.

Я знаю, это грязно. Но если в текущем SDK нет альтернативного API , это должно быть безопасно. Как только выйдет новая версия Xcode, изменение будет перезаписано, и вы снова увидите предупреждение. Затем вы можете протестировать новый SDK и ОС, чтобы убедиться, что устаревший API по-прежнему доступен и не получил замены.

Прокомментируйте, если вы заметите какие-либо недостатки.

Pointum
источник
Проголосовал за находчивость, но это оставило бы неприятный привкус во рту: П
Мэтт,