Tipo de pregunta nerd. No me queda claro qué es exactamente lo que hace que este código funcione:
class Shape { } extension Shape { @objc func redraw() { print("from ext") } } class Circle: Shape { } class Line: Shape { override func redraw() { // Compiler error: Declarations from extensions cannot be overridden yet print("from subclass") } } let line = Line() let shape:Shape = line let circle = Circle() line.redraw() //from subclass circle.redraw() //from ext shape.redraw() //from subclass Si omito la palabra clave @objc en la extensión, el código no se compilará; es el comportamiento esperado ya que los métodos en la extensión usan el envío de métodos estáticos -> no se pueden anular. Pero, ¿por qué agregar @objc hace que funcione? De acuerdo con la documentación y la mayoría de los artículos, todo lo que hace @objc es hacer que las cosas sean visibles para el tiempo de ejecución de Objective-c. Para cambiar el tipo de envío del método, hay una palabra clave especial: dynamic . ¡Pero parece que no es necesario aquí!
Ayúdame a descubrir por qué agregar @objc (y omitir dynamic ) hace que tales cosas sean posibles.
como ya lo dice el nombre, se supone que extienden/agregan/incluyen métodos a una implementación existente, lo que los convierte en una de las cosas más hermosas de Objective-C, y ahora Swift, ya que puede agregar código a una clase o marco que no propio. Por lo tanto, tiene sentido que no debas "reemplazar" el código en las extensiones, conceptualmente hablando.
Es por eso que el compilador se queja cuando intentas hacerlo.
También mira esta respuesta .
sin embargo, esto también parece ser un problema de soporte, ya que el compilador rápido simplemente arroja este error:
No se admite la anulación de declaraciones que no sean @objc de extensiones.
Según Apple,
Las extensiones pueden agregar una nueva funcionalidad a un tipo, pero no pueden anular la funcionalidad existente.
Pero ese no es el caso, ya que estamos anulando la extensión y no al revés, lo que nos lleva de vuelta a la declaración de extension .
Las extensiones agregan nueva funcionalidad a una clase, estructura, enumeración o tipo de protocolo existente. Esto incluye la capacidad de ampliar tipos para los que no tiene acceso al código fuente original (conocido como modelado retroactivo). Las extensiones son similares a las categorías en Objective-C. (A diferencia de las categorías de Objective-C, las extensiones de Swift no tienen nombres).Aquí .
Volviendo al tema heredado del compilador rápido frente al compilador Objc,
Despacho dinámico vs. Despacho estático .
Y no hay documentación oficial de Apple sobre por qué esto no es compatible con el compilador rápido o si tienen planes futuros para solucionarlo o si lo consideran un problema.
Sin embargo , no existe el despacho dinámico de Swift; solo tenemos el envío dinámico del tiempo de ejecución de Objective-C. Eso significa que no puede tener solo dinámica y debe escribir @objc dinámica. Entonces, esta es efectivamente la misma situación que antes, solo que explícita.
Y aquí hay un gran artículo que habla sobre este tema en profundidad.