Использование Swift 3 @objc в режиме Swift 4 не рекомендуется?

Вкратце, при использовании Xcode 9 Beta я столкнулся со следующим предупреждением:

Использование Swift 3 @objc в режиме Swift 4 не рекомендуется. Обратите внимание на устаревшие предупреждения @objc, проверьте ваш код с включенным ведением журнала "Использование устаревшего Swift 3 @objc" и отключите Swift 3 @objc.**

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

Моя цель - лучше понять, что происходит с моим кодом.

9 ответов

Я избавился от этого предупреждения, изменив настройку сборки "Swift 3 @objc Inference" моих целей на "Default".

Отключить вывод Swift 3 @objc в Xcode9

Из этой статьи:

До Swift 4 компилятор делал некоторые объявления Swift автоматически доступными для Objective-C. Например, если один подкласс из NSObject, компилятор создал точки входа Objective C для всех методов в таких классах. Механизм называется выводом @objc.

В Swift 4 такой автоматический вывод @objc устарел, поскольку генерировать все эти точки входа в Objective-C дорого. Если для параметра "Swift 3 @objc Inference" установлено значение "Вкл.", Это позволяет старому коду работать. Тем не менее, он покажет предупреждения об устаревании, которые необходимо устранить. Рекомендуется "исправить" эти предупреждения и переключить настройку на "По умолчанию", которая используется по умолчанию для новых проектов Swift.

Пожалуйста, также обратитесь к этому предложению Swift для получения дополнительной информации.

- Что такое @objc статистические выводы? Что здесь происходит?

В Swift 3 компилятор выводит @objc в ряде мест, чтобы вам не пришлось. Другими словами, это обязательно добавить @objc для тебя!

В Swift 4 компилятор больше не делает это (так много). Теперь вы должны добавить @objc в явном виде.

По умолчанию, если у вас есть проект до Swift 4, вы получите предупреждения об этом. В проекте Swift 4 вы получите ошибки сборки. Это контролируется через SWIFT_SWIFT3_OBJC_INFERENCE Построить настройки. В проекте до Swift 4 это установлено на On, Я бы порекомендовал установить это Default (или же Off ), которая теперь является опцией по умолчанию для нового проекта.

Конвертация всего займет некоторое время, но поскольку это Swift 4 по умолчанию, его стоит сделать.

Я могу остановить предупреждения / ошибки компилятора?

Есть два способа преобразования вашего кода, чтобы компилятор не жаловался.

Одним из них является использование @objc на каждую функцию или переменную, которая должна быть представлена ​​среде выполнения Objective C:

@objc func foo() {

}

Другой должен использовать @objcMembers по Class декларация. Это обеспечивает автоматическое добавление @objc для ВСЕХ функций и переменных в классе. Это простой способ, но он имеет свою стоимость, например, он может увеличить размер вашего приложения, предоставляя функции, которые не нужно показывать.

@objcMembers class Test {

}

- Что такое @objc а зачем это нужно?

Если вы вводите новые методы или переменные в класс Swift, пометьте их как @objc выставляет их для выполнения Objective-C. Это необходимо, когда у вас есть код Objective C, который использует ваш класс Swift, или если вы используете функции типа Objective C, такие как Selectors, Например, шаблон target-action: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

- Почему бы мне не отметить все @objc?

Есть негативы, которые идут с маркировкой чего-то как @objc:

  • Увеличенный размер двоичного файла приложения
  • Нет перегрузки функции

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

Источники:

Migrator не может идентифицировать все функции, для которых нужны пометки @objc Inferred Objective-C, помеченные как устаревшие, чтобы помочь вам их найти
• Создавать предупреждения о устаревших методах
• Консольные сообщения при запуске устаревших thunks

У меня было это предупреждение с настройкой "Swift 3 @objc Inference" = "По умолчанию". Тогда я понял, что это было установлено для Проекта, а не для цели. Итак, убедитесь, что у вас есть настройка "Default" в вашей цели, чтобы избавиться от предупреждения.

Вы можете просто перейти к "по умолчанию" вместо "ON". Кажется, более привержен к логике Apple.

(но все остальные комментарии об использовании @obj остается в силе.)

Вы можете попробовать "Pod update" и / или "flutter clean"

Я также установил эту настройку в xcode.

Настройка интерфейса Objective-C выглядит следующим образом:

Настройка интерфейса ObjectiveC

Я случайный разработчик iOS (скоро будет больше), но я все еще не мог найти настройку, руководствуясь другим ответом (так как у меня не было этого элемента цепочки для ключей, который показывает ответ), так что теперь, когда я нашел его, я подумал Я мог бы просто добавить этот снимок с выделенными местами, которые вам нужно будет щелкнуть и найти.

  1. Начало в верхнем левом углу
  2. Выберите значок папки проекта
  3. Выберите название своего основного проекта под значком папки проекта.
  4. Выберите Настройки сборки на правой стороне.
  5. Выберите ваш проект под ЦЕЛЕЙ.
  6. Прокрутка очень далеко вниз (или поиск слова в текстовом поле поиска)

Нахождение настройки

Действительно, вы избавитесь от этих предупреждений, отключив Swift 3 @objc Inference. Тем не менее, могут возникнуть тонкие проблемы. Например, КВО перестанет работать. Этот код отлично работал под Swift 3:

for (key, value) in jsonDict {
    if self.value(forKey: key) != nil {
        self.setValue(value, forKey: key)
    }
}

После перехода на Swift 4 и установки по умолчанию "Swift 3 @objc Inference" некоторые функции моего проекта перестали работать. Мне потребовались некоторые отладки и исследования, чтобы найти решение для этого. Насколько я знаю, вот варианты:

  • Включить "Swift 3 @objc Inference" (работает, только если вы перенесли существующий проект из Swift 3) введите описание изображения здесь
  • Отметьте затронутые методы и свойства как @objc введите описание изображения здесь
  • Повторно включите вывод ObjC для всего класса, используя @objcMembers введите описание изображения здесь

Повторное включение вывода @objc оставляет вас с предупреждениями, но это самое быстрое решение. Обратите внимание, что он доступен только для проектов, перенесенных из более ранней версии Swift. Два других варианта более утомительны и требуют некоторого копания кода и тщательного тестирования.

Смотрите также https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md

Swift 3 @objc Inference Использование Swift 3 @objc Inference в режиме Swift 4 не рекомендуется. Пожалуйста, рассмотрите устаревшие предупреждения @objc inference, проверьте свой код с включенным ведением журнала "Использование устаревшего Swift 3 @objc inference", а затем отключите вывод, изменив настройку сборки "Swift 3 @objc Inference" на "Default" для "XMLParsingURL" цель.

добрался до

  1. Первый шаг получил настройки сборки

  2. Ищите, чтобы построить вывод настроек

  3. change swift 3 @objc Inference Default

введите описание изображения здесь

Помимо того, что сказал @wisekiddo, вы также можете изменить настройки сборки в project.pbxproj файл, установив Swift 3 @obj Inference в значение по умолчанию, как SWIFT_SWIFT3_OBJC_INFERENCE = Default; для ваших сборок (например, отладка и выпуск), особенно если вы пришли из другой среды, кроме XCode

Использование Swift 3 @objc в режиме Swift 4 не рекомендуется?

используйте func call @objc

func call(){

foo()

}

@objc func foo() {

}

Все, что вам нужно, это просто запустить тестовое ожидание до конца, после этого перейдите в "Настройка сборки", "Поиск в выводе параметров сборки", измените swift 3 @objc Inference на (по умолчанию). это все, что я делал и работал отлично.

Другие вопросы по тегам