Xcode 8/Swift 3: Advertencia "¿La expresión de tipo UIViewController? No se utiliza"
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 del tipo" UIViewController? "no se utiliza".
¿Por qué dice esto y hay alguna forma de eliminarlo?
El código se ejecuta como se esperaba.
TL;DR
popViewController(animated:)
devuelve UIViewController?
y el compilador da 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" de forma predeterminada. No se produciría ninguna advertencia si no capturara lo que devolvió el método.
Para decirle al compilador que el resultado debe capturarse, debía agregarlo @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
). Agregaría @warn_unused_result(mutable_variant="mutableMethodHere")
informarle al compilador.
Sin embargo, con Swift 3, el comportamiento cambia. 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, agréguela @discardableResult
antes de la declaración del método.
Si no desea utilizar el valor de retorno, debe indicarlo 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 (ej. usar
sort
pensando que modifica la colección) - Intención explícita de no capturar o necesitar capturar el resultado para otros colaboradores
La API UIKit parece estar atrasada en esto, sin agregar @discardableResult
para el uso perfectamente normal (si no más común) popViewController(animated:)
sin capturar el valor de retorno.
Leer más
- SE-0047 Propuesta de evolución rápida
- Propuesta aceptada con revisiones.
Cuando la vida te dé 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 esto @discardableResult func pop(animated: Bool) -> UIViewController?
generará 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 genera una advertencia.
Una forma de excluirse de esto es marcar la función con el @discardableResult
atributo. 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 usted sabe que el método devuelve un valor pero que no desea retenerlo en la memoria.
let _ = navigationController?.popViewController(animated: true)