Xcode 8/Swift 3: Advertencia "¿La expresión de tipo UIViewController? No se utiliza"

Resuelto Piepants asked hace 54 años • 7 respuestas

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.

Piepants avatar Jan 01 '70 08:01 Piepants
Aceptado

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_resultantes de la declaración del método. Se usaría para métodos que tienen una forma mutable (por ejemplo, sorty 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 @discardableResultantes 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 sortpensando 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 @discardableResultpara 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.
tktsubota avatar Jun 15 '2016 19:06 tktsubota

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.

CodeReaper avatar Oct 19 '2016 11:10 CodeReaper

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 @discardableResultatributo. 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)
Matthew Seaman avatar Jun 15 '2016 19:06 Matthew Seaman