tutorial the programming programación lenguaje language book apple ios swift

ios - the - Xcode 8/Swift 3: “Expresión del tipo UIViewController? está sin usar "advertencia



the swift programming language 4.2 pdf (7)

Tengo la siguiente función que se compiló limpiamente anteriormente pero genera una advertencia con Xcode 8.

func exitViewController() { navigationController?.popViewController(animated: true) }

"La expresión de tipo" UIViewController? "No está en uso".

¿Por qué dice esto y hay una manera de eliminarlo?

El código se ejecuta como se esperaba.


TL; DR

popViewController(animated:) devuelve UIViewController? , y el compilador está dando esa advertencia ya que no está capturando el valor. La solución es asignarlo a un guión bajo:

_ = navigationController?.popViewController(animated: true)

Cambio rápido 3

Antes de Swift 3, todos los métodos tenían un "resultado descartable" por defecto. No se produciría ninguna advertencia cuando no capturara lo que devolvió el método.

Para decirle al compilador que se debe capturar el resultado, debe agregar @warn_unused_result antes de la declaración del método. Se usaría para métodos que tienen una forma mutable (por ejemplo, sort y sortInPlace ). @warn_unused_result(mutable_variant="mutableMethodHere") para informarle al compilador.

Sin embargo, con Swift 3, el comportamiento se voltea. Todos los métodos ahora advierten que el valor de retorno no se captura. Si desea decirle al compilador que la advertencia no es necesaria, agregue @discardableResult antes de la declaración del método.

Si no desea utilizar el valor de retorno, debe decirle explícitamente al compilador asignándolo a un guión bajo:

_ = someMethodThatReturnsSomething()

Motivación para agregar esto a Swift 3:

  • Prevención de posibles errores (por ejemplo, usando el pensamiento de modificación de la colección)
  • Intento explícito de no capturar o necesitar capturar el resultado para otros colaboradores

La API de UIKit parece estar retrasada en esto, sin agregar @discardableResult para el uso perfectamente normal (si no más común) de popViewController(animated:) sin capturar el valor de retorno.

Lee mas


Cuando la vida te da limones, haz una extensión:

import UIKit extension UINavigationController { func pop(animated: Bool) { _ = self.popViewController(animated: animated) } func popToRoot(animated: Bool) { _ = self.popToRootViewController(animated: animated) } }

Tenga en cuenta que agregar algo como @discardableResult func pop(animated: Bool) -> UIViewController? resultará en la misma advertencia que está tratando de evitar.

Con la extensión ahora puedes escribir:

func exitViewController() { navigationController?.pop(animated: true) } func popToTheRootOfNav() { navigationController?.popToRoot(animated: true) }

Editar: También se agregó popToRoot.


En Swift 3, ignorar el valor de retorno de una función que tiene un valor de retorno declarado da como resultado una advertencia.

Una forma de @discardableResult esta opción es marcar la función con el atributo @discardableResult . Como no tienes control sobre esta función, eso no funcionará.

El otro método para deshacerse de la advertencia es asignar el valor a _ . Esto le dice al compilador que sabe que el método devuelve un valor pero que no desea retenerlo en la memoria.

let _ = navigationController?.popViewController(animated: true)


Otra forma es ¿puedes self.navigationController? el self.navigationController? valor y llame a la función popViewController .

if let navigationController = navigationController { navigationController.popViewController(animated: true) }


Si desea seguir el camino de las extensiones como la respuesta de CodeReaper, debe usar @descardableResult . Esto mantiene todas las posibilidades, pero silencia la advertencia.

import UIKit extension UINavigationController { @discardableResult func pop(animated: Bool) -> UIViewController? { return self.popViewController(animated: animated) } @discardableResult func popToRoot(animated: Bool) -> [UIViewController]? { return self.popToRootViewController(animated: animated) } }


Utilice el resultado descartable en esta condición.

De acuerdo con <Swift Programming Language>, capítulo Referencia del lenguaje - Atributos.

resultado descartable

Aplique este atributo a una declaración de función o método para suprimir la advertencia del compilador cuando se llama a la función o método que devuelve un valor sin usar su resultado.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Attributes.html#//apple_ref/doc/uid/TP40014097-CH35-ID347

También hay una demostración en <Swift Programming Language>, capítulo Guía del lenguaje - Métodos.

@discardableResult mutating func advance(to level: Int) -> Bool { ... return true }

Debido a que no es necesariamente un error para el código que llama al método advance (to :) para ignorar el valor de retorno, esta función está marcada con el atributo @discardableResult. Para obtener más información sobre este atributo, vea Atributos.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html#//apple_ref/doc/uid/TP40014097-CH15-ID234


Aunque work correctly if kept as it is pero number of warning increases. el number of warning increases.

La solución es simplemente replace it with underscore ( _ ) aunque parezca feo.

Eg. _ = navigationController?.popViewController(animated: true)