swift swift4 xcode9-beta

¿El uso de la inferencia Swift 3 @objc en el modo Swift 4 está en desuso?



swift4 xcode9-beta (12)

Brevemente, mientras uso Xcode 9 Beta, me he encontrado con la siguiente advertencia:

El uso de la inferencia Swift 3 @objc en el modo Swift 4 está en desuso. Dirija las advertencias de inferencia obsoleta @objc, pruebe su código con el registro "Uso de inferencia obsoleta Swift 3 @objc" habilitado y desactive la inferencia Swift 3 @objc. **

Después de un poco de investigación, todavía no tengo idea de cómo solucionar el problema. Agradecería mucho cualquier consejo sobre cómo solucionar este problema, así como una explicación de lo que está sucediendo.

Mi objetivo es comprender mejor lo que está sucediendo con mi código.


¿El uso de la inferencia Swift 3 @objc en el modo Swift 4 está en desuso?

use func call @objc

func call(){ foo() } @objc func foo() { }


- ¿Qué es la inferencia @objc ? Que esta pasando?

En Swift 3 , el compilador infiere @objc en varios lugares para que no tenga que hacerlo. En otras palabras, ¡se asegura de agregar @objc por ti!

En Swift 4 , el compilador ya no hace esto (tanto). Ahora debe agregar @objc explícitamente.

Por defecto, si tiene un proyecto anterior a Swift 4, recibirá advertencias al respecto. En un proyecto Swift 4, obtendrá errores de compilación. Esto se controla mediante la SWIFT_SWIFT3_OBJC_INFERENCE compilación SWIFT_SWIFT3_OBJC_INFERENCE . En un proyecto anterior a Swift 4, esto se establece en On . Recomendaría establecer esto en Default (o Off ), que ahora es la opción predeterminada en un nuevo proyecto.

Tomará algún tiempo convertir todo, pero dado que es el valor predeterminado para Swift 4, vale la pena hacerlo.

- ¿Cómo detengo las advertencias / errores del compilador?

Hay dos formas de convertir su código para que el compilador no se queje.

Una es usar @objc en cada función o variable que necesita exponerse al tiempo de ejecución de Objective-C:

@objc func foo() { }

El otro es usar @objcMembers por una declaración de Class . Esto se asegura de agregar automáticamente @objc a TODAS las funciones y variables en la clase. Esta es la manera fácil, pero tiene un costo, por ejemplo, puede aumentar el tamaño de su aplicación al exponer funciones que no necesitaban estar expuestas.

@objcMembers class Test { }

- ¿Qué es @objc y por qué es necesario?

Si introduce nuevos métodos o variables en una clase Swift, marcándolos como @objc expone al tiempo de ejecución de Objective-C. Esto es necesario cuando tiene un código Objective-C que usa su clase Swift o, si está usando características de tipo Objective-C como Selectors . Por ejemplo, el patrón de acción de destino: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

- ¿Por qué no marcaría todo @objc ?

Hay @objc negativos que vienen con marcar algo como @objc :

  • Aumento del tamaño binario de la aplicación.
  • Sin sobrecarga de funciones

Tenga en cuenta que este es un resumen de muy alto nivel y que es más complicado de lo que escribí. Recomendaría leer la propuesta real para obtener más información.

Fuentes:


Además de lo que dijo @wisekiddo, también puede modificar su configuración de compilación en el archivo project.pbxproj configurando la Inferencia Swift 3 @obj como predeterminada, como SWIFT_SWIFT3_OBJC_INFERENCE = Default; para sus sabores de compilación (es decir, depuración y lanzamiento), especialmente si viene de otro entorno además de Xcode


De hecho, se deshará de esas advertencias deshabilitando Swift 3 @objc Inference. Sin embargo, pueden surgir problemas sutiles. Por ejemplo, KVO dejará de funcionar. Este código funcionó perfectamente en Swift 3:

for (key, value) in jsonDict { if self.value(forKey: key) != nil { self.setValue(value, forKey: key) } }

Después de migrar a Swift 4 y configurar "Swift 3 @objc Inference" de manera predeterminada, ciertas funciones de mi proyecto dejaron de funcionar . Me tomó un poco de depuración e investigación para encontrar una solución para esto. Según mi mejor conocimiento, estas son las opciones:

  • Habilite "Inferencia Swift 3 @objc" (solo funciona si migró un proyecto existente desde Swift 3)
  • Marque los métodos y propiedades afectados como @objc
  • Vuelva a habilitar la inferencia ObjC para toda la clase usando @objcMembers

Volver a habilitar la inferencia @objc te deja con las advertencias, pero es la solución más rápida. Tenga en cuenta que solo está disponible para proyectos migrados desde una versión anterior de Swift. Las otras dos opciones son más tediosas y requieren un poco de excavación de código y pruebas exhaustivas.

Ver también https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md


El migrador no puede identificar todas las funciones que necesitan los troncos @objc Inferred Objective-C marcados como obsoletos para ayudarlo a encontrarlos
• Crear advertencias sobre métodos obsoletos
• Mensajes de la consola cuando se ejecutan thunks obsoletos


Eliminé esta advertencia al cambiar la configuración de compilación "Swift 3 @objc Inference" de mis objetivos a "Predeterminado".

De este artículo :

Antes de Swift 4, el compilador hizo algunas declaraciones Swift disponibles automáticamente para Objective-C . Por ejemplo, si se subclasificó de NSObject, el compilador creó puntos de entrada Objective-C para todos los métodos en tales clases. El mecanismo se llama inferencia @objc.

En Swift 4, dicha inferencia automática @objc está en desuso porque es costoso generar todos esos puntos de entrada de Objective-C. Cuando la configuración "Swift 3 @objc Inference" se establece en "On", permite que el código anterior funcione. Sin embargo, mostrará advertencias de desaprobación que deben abordarse. Se recomienda "corregir" estas advertencias y cambiar la configuración a "Predeterminado" , que es el valor predeterminado para los nuevos proyectos de Swift.

Consulte también esta propuesta de Swift para obtener más información.


Inferencia Swift 3 @objc El uso de la inferencia Swift 3 @objc en el modo Swift 4 está en desuso. Dirija las advertencias de inferencia obsoleta @objc, pruebe su código con el registro "Uso de inferencia obsoleta Swift 3 @objc" habilitado, y luego desactive la inferencia cambiando la configuración de compilación "Inferencia Swift 3 @objc" a "Predeterminado" para "XMLParsingURL" objetivo.

llegué a la

  1. El primer paso consiguió la configuración de compilación

  2. Buscar para generar inferencia de configuración

  3. cambiar swift 3 @objc Inferencia Predeterminado

ingrese la descripción de la imagen aquí


Puede intentar "Actualizar pod" y / o "limpiar el aleteo"

También configuré esta configuración en xcode.

La configuración de la interfaz Objective-C es la siguiente:


Recibí esta advertencia con la configuración "Swift 3 @objc Inference" = "Predeterminado". Entonces me di cuenta de que estaba configurado para el Proyecto, no para el objetivo. Por lo tanto, asegúrese de tener la configuración "Predeterminada" en su objetivo para deshacerse de la advertencia.


Simplemente puede pasar a "predeterminado" en lugar de "ON". Parece más adherente a la lógica de Apple.

(pero todos los otros comentarios sobre el uso de @obj siguen siendo válidos).


Soy un desarrollador de iOS ocasional (pronto será más) pero todavía no pude encontrar la configuración según la otra respuesta (ya que no tenía ese elemento de Llavero que muestra la respuesta), así que ahora que lo encontré pensé Podría agregar esta instantánea con las ubicaciones resaltadas en las que deberá hacer clic y buscar.

  1. Comience en la esquina superior izquierda
  2. Elija el icono de la carpeta del proyecto
  3. Elija su nombre de proyecto principal debajo del icono de la carpeta del proyecto.
  4. Elija Configuración de compilación en el lado derecho.
  5. Elija su proyecto en OBJETIVOS.
  6. Desplácese muy hacia abajo (o busque la palabra inferencia en el cuadro de texto de búsqueda)


Todo lo que necesita es ejecutar una prueba, esperar hasta que termine, luego vaya a Configuración de compilación, Buscar en Inferencia de configuración de compilación, cambie la Inferencia rápida de 3 @objc a (Predeterminado). Eso es todo lo que hice y funcionó perfectamente.