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

402

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

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

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

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

  • 3
    Я действительно не получаю из предупреждающего сообщения, какой объект вызывает его. Xcode просто не говорит, в какой строке находится этот объект. Любые советы, как узнать, откуда это предупреждение?
Теги:
swift4
xcode9-beta

10 ответов

712

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

Изображение 1615

Из в этой статье:

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

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

Дополнительную информацию см. это предложение Swift.

  • 5
    Спасибо Евгений. Это долгосрочное решение?
  • 5
    @DaleK да, я верю в это. Согласно предложению Свифта, которое я упомянул в своем ответе, вывод объекта устарел. Параметр «Swift 3 objc Inference» присутствует только в проектах, которые были перенесены из более старых версий Swift. Если создается новый проект, настройка больше не присутствует, а это значит, что вывод объекта отключен. Рекомендуется адресовать любые предупреждения об объектном выводе и установить для него значение «Выкл.».
Показать ещё 12 комментариев
228

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

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

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

По умолчанию, если у вас есть проект до Swift 4, вы получите предупреждения об этом. В проекте Swift 4 вы получите ошибки сборки. Это контролируется SWIFT_SWIFT3_OBJC_INFERENCE сборки 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 как @objc:

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

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

Источники:

  • 0
    @objc не подразумевает динамическую диспетчеризацию, Swift может использовать статическую или виртуальную диспетчеризацию (и, возможно, в результате выполнить другой код). Ключевое слово dynamic требуется, чтобы заставить Swift использовать динамическую диспетчеризацию.
  • 7
    Есть ли другие способы добавить действие к кнопке? Если @objc dericated, что мы должны использовать?
Показать ещё 6 комментариев
43

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

Изображение 1616

  • 1
    Так что мне делать с @objc? убери это? Оставь это? Я уже удалил это. и я получил эти предупреждения, так что я должен добавить их? что на шаге 3 мне делать с этим?
  • 0
    Добавьте @objc непосредственно перед func
Показать ещё 2 комментария
8

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

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

7

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

  • 0
    Я потратил впустую 20 минут, пытаясь устранить ошибку, даже после того, как я изменил значение по умолчанию в настройках проекта. Вы указали точно, что это должно быть изменено в цели также.
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) Изображение 1617
  • Отметьте затронутые методы и свойства как @objc Изображение 1618
  • Повторно включите вывод ObjC для всего класса, используя @objcMembers Изображение 1619

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

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

2

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

попал в

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

  • Искать в построении вывода настроек

  • change swift 3 @objc Вывод по умолчанию

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

0

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

0

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

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

Изображение 1620

0

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

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

func call(){

foo()

}

@objc func foo() {

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню