Использование 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 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 выглядит следующим образом:
Я случайный разработчик iOS (скоро будет больше), но я все еще не мог найти настройку, руководствуясь другим ответом (так как у меня не было этого элемента цепочки для ключей, который показывает ответ), так что теперь, когда я нашел его, я подумал Я мог бы просто добавить этот снимок с выделенными местами, которые вам нужно будет щелкнуть и найти.
- Начало в верхнем левом углу
- Выберите значок папки проекта
- Выберите название своего основного проекта под значком папки проекта.
- Выберите Настройки сборки на правой стороне.
- Выберите ваш проект под ЦЕЛЕЙ.
- Прокрутка очень далеко вниз (или поиск слова в текстовом поле поиска)
Действительно, вы избавитесь от этих предупреждений, отключив 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" цель.
добрался до
Первый шаг получил настройки сборки
Ищите, чтобы построить вывод настроек
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 на (по умолчанию). это все, что я делал и работал отлично.