Swift 3 - динамический vs @objc
Какая разница между маркировкой метода как @objc vs dynamic, когда вы делаете одно против другого?
Ниже приведено определение Apple для динамического.
dynamic Применить этот модификатор к любому члену класса, который может быть представленный Objective-C. Когда вы отмечаете объявление участника с помощью динамический модификатор, доступ к этому элементу всегда динамически отправлен с использованием среды выполнения Objective-C. Доступ к этому члену никогда не встроенный или девиртуализированный компилятором.
Поскольку объявления, помеченные динамическим модификатором, отправляются используя Objective-C runtime, theyre неявно отмечен objc атрибут.
Ответы
Ответ 1
Функция/переменная, объявленная как @objc
, доступна из Objective-C, но Swift будет продолжать обращаться к ней напрямую через статическую или виртуальную отправку.
Это означает, что если функция/переменная swizzled через фреймворк Objective-C, например, что происходит при использовании Key-Value Observing или различных API Objective-C для изменения классов, вызов метода из Swift и Objective-C приведет к различным результатам.
Использование dynamic
указывает Swift всегда ссылаться на динамическую отправку Objective-C.
Это необходимо для правильной работы таких вещей, как Key-Value Observing. Когда вызывается функция Swift, она ссылается на Objective-C время выполнения, чтобы динамически отправлять вызов.
Ответ 2
Как говорится в этой цитате, dynamic
подразумевает @objc
.
Если вы не укажете класс как dynamic
, компилятор может свободно оптимизировать и встроить свои методы. Это приносит огромные преимущества в производительности, но это означает, что вы не можете изменить эти реализации метода во время выполнения. Если вы планируете возиться с этими методами во время выполнения, используя возможности отражения времени выполнения Objective C, вам нужно использовать dynamic
. Вы понесете штраф за производительность (ваш код будет работать на уровнях уровня Objective C, а не вблизи уровней C), но вы получите дополнительный динамизм.
Ответ 3
При взаимодействии необходимо учитывать два ключевых слова:
В Swift 3 и более ранних версиях dynamic
также подразумевал @objc
. Новое в Swift 4, dynamic
означает только динамическую диспетчеризацию и ничего не говорит о видимости Objective-C.
Однако нет такой вещи как Swift динамическая отправка; у нас есть только динамическая диспетчеризация Objective-C. Это означает, что вы не можете иметь только динамику, и вы должны написать @objc dynamic
. Так что это фактически та же самая ситуация, что и раньше, только что была сделана явной.
Подробнее здесь