Probé un poco de isa swizzling con Swift, y descubrí que solo funciona cuando NSObject es una superclase (directamente o más arriba), o usando la decoración '@objc'. De lo contrario, seguirá un estilo de envío estático y vtable, como C ++.
¿Es normal definir una clase Swift sin una clase base Cocoa / NSObject? Si me preocupa, esto significa renunciar a gran parte del dinamismo de Objective-C, como la interceptación de métodos y la introspección en tiempo de ejecución.
El comportamiento dinámico en tiempo de ejecución se encuentra en el corazón de funciones como los observadores de propiedades, los datos centrales, la programación orientada a aspectos , la mensajería de orden superior , los marcos analíticos y de registro, etc.
El uso del estilo de invocación de métodos de Objective-C agrega alrededor de 20 operandos de código de máquina a una llamada de método, por lo que en ciertas situaciones ( muchas llamadas ajustadas a métodos con cuerpos pequeños ) el envío estático y vtable de estilo C ++ puede funcionar mejor.
Pero dada la regla general 95-5 (el 95% de las ganancias de rendimiento provienen de ajustar el 5% del código ), ¿no tiene sentido comenzar con las potentes funciones dinámicas y endurecerlas cuando sea necesario?
fuente
Respuestas:
Clases Swift que son subclases de NSObject:
objc_msgSend()
para llamadas a (la mayoría de) sus métodosClases Swift que no son subclases de NSObject:
objc_msgSend()
para llamadas a sus métodos (por defecto)Subclasificar NSObject en Swift le brinda flexibilidad en el tiempo de ejecución de Objective-C pero también rendimiento de Objective-C. Evitar NSObject puede mejorar el rendimiento si no necesita la flexibilidad de Objective-C.
Editar:
Con Xcode 6 beta 6, aparece el atributo dinámico. Esto nos permite indicarle a Swift que un método debe utilizar el envío dinámico y, por lo tanto, admitirá la interceptación.
fuente
También descubrí que si basaba una clase Swift en NSObject, veía un comportamiento inesperado en tiempo de ejecución que podía ocultar errores de codificación. Aquí hay un ejemplo.
En este ejemplo, donde no nos basamos en NSObject, el compilador detecta correctamente el error en testIncorrect_CompilerShouldSpot, informando "... 'MyClass' no es convertible a 'MirrorDisposition'"
En este ejemplo, donde nos basamos en NSObject , el compilador no detecta el error en testIncorrect_CompilerShouldSpot:
Supongo que la moraleja es, ¡solo base en NSObject donde realmente tienes que hacerlo!
fuente
De acuerdo con la referencia del lenguaje, no hay ningún requisito para que las clases subclasifiquen ninguna clase raíz estándar, por lo que puede incluir u omitir una superclase según sea necesario.
Tenga en cuenta que omitir una superclase de la declaración de clase no asigna una superclase base implícita de ningún tipo. Define una clase base, que se convertirá efectivamente en la raíz de una jerarquía de clases independiente.
De la referencia del idioma:
Intentar hacer referencia
super
desde una clase sin una superclase (es decir, una clase base) resultará en un error de tiempo de compilaciónfuente
Creo que la gran mayoría de los datos de Swift no lo serán
objc
. Solo aquellas partes que necesiten comunicarse con la infraestructura del Objetivo C se marcarán explícitamente como tales.Hasta qué punto se agregará la introspección en tiempo de ejecución al lenguaje, no lo sé. La interceptación de métodos probablemente solo sea posible si el método lo permite explícitamente. Esta es mi suposición, pero solo los diseñadores de lenguajes de Apple saben realmente hacia dónde se dirigen.
fuente
educated guesses
en unos años a partir de ahora. Pero por el momento es solo un gran signo de interrogación.Lo siguiente es una copia del Swift-eBook de Apple y da una respuesta adecuada a su pregunta:
Definición de una clase base
Cualquier clase que no herede de otra clase se conoce como clase base.
Las clases rápidas no heredan de una clase base universal. Las clases que defina sin especificar una superclase se convertirán automáticamente en clases base sobre las que podrá construir.
Referencia
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251fuente
Es normal. Mire los objetivos de diseño de Swift: el objetivo es hacer desaparecer grandes clases de problemas de programación. El método swizzling probablemente no sea una de las cosas que quieras hacer con Swift.
fuente