Xcode 8 / Swift 3: "Expresión de tipo UIViewController? no se utiliza " advertencia


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

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

"Expresión de tipo" UIViewController?"no se usa".

¿Por qué está diciendo esto y hay una manera de eliminarlo?

El código se ejecuta como se espera.

 226
Author: Gruntcakes, 2016-06-15

7 answers

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 guion bajo:

_ = navigationController?.popViewController(animated: true)

Cambio Swift 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 devolvía el método.

Para decirle al compilador que el resultado debe ser capturado, tuvo que agregar @warn_unused_result antes del método declaración. Se usaría para métodos que tienen una forma mutable (ex. sort y sortInPlace). Usted agregaría @warn_unused_result(mutable_variant="mutableMethodHere") para decirle al compilador de ello.

Sin embargo, con Swift 3, el comportamiento se invierte. Ahora todos los métodos advierten que el valor devuelto 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 devuelto, tiene que explícitamente decirle al compilador asignándole un subrayado:

_ = someMethodThatReturnsSomething()

Motivación para agregar esto a Swift 3:

  • Prevención de posibles errores (ej. usando sort pensando que modifica la colección)
  • Intención explícita de no capturar o necesidad de capturar el resultado para otros colaboradores

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

Leer Más

 492
Author: tktsubota,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 18:11:28

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 puede escribir:

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

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

Editar: También se agregó popToRoot.

 38
Author: CodeReaper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-19 13:15:18

En Swift 3, ignorar el valor de retorno de una función que tiene un valor de retorno declarado resulta en una advertencia.

Una forma de optar por esto es marcar la función con el atributo @discardableResult. Dado que no tiene 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)
 24
Author: Matthew Seaman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-20 02:06:19

Captura de pantalla 1

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

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

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

Captura de pantalla 2

 5
Author: Jayprakash Dubey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-31 15:48:42

Use discardableResult en esta condición.

De acuerdo con , chapter Language Reference - Attributes.

Resultados descartables

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 demo en , chapter Language Guide - Methods.

@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 devuelto, esta función se marca con el @discardableResult atributo. Para obtener más información sobre este atributo, consulte Atributos.

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

 1
Author: black_pearl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 06:20:05

Si quieres ir por el camino de extensiones como Codereaper's answer deberías 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)
    }
}
 0
Author: Casper Zandbergen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-22 10:49:24

Otra forma es abrir el valor self.navigationController? y llamar a la función popViewController.

    if let navigationController = navigationController {
        navigationController.popViewController(animated: true)
    }
 -1
Author: muazhud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-08 02:12:30