web-dev-qa-db-fra.com

Xcode 8/Swift 3: avertissement "Une expression de type UIViewController? N'est pas utilisée"

J'ai la fonction suivante qui compile proprement auparavant mais génère un avertissement avec Xcode 8.

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

"Expression de type" UIViewController? "N'est pas utilisée".

Pourquoi dit-il cela et y a-t-il un moyen de l'enlever?

Le code s'exécute comme prévu.

226
Gruntcakes

TL; DR

popViewController(animated:) renvoie UIViewController? et le compilateur donne cet avertissement, car vous ne capturez pas la valeur. La solution consiste à l'attribuer à un trait de soulignement:

_ = navigationController?.popViewController(animated: true)

Swift 3 Changement

Avant Swift 3, toutes les méthodes avaient un "résultat à écarter" par défaut. Aucun avertissement ne se produit lorsque vous ne capturez pas ce que la méthode a renvoyé.

Afin d'indiquer au compilateur que le résultat devrait être capturé, vous deviez ajouter @warn_unused_result avant la déclaration de la méthode. Il serait utilisé pour les méthodes ayant une forme mutable (par exemple, sort et sortInPlace). Vous ajouteriez @warn_unused_result(mutable_variant="mutableMethodHere") pour en informer le compilateur.

Cependant, avec Swift 3, le comportement est inversé. Toutes les méthodes avertissent maintenant que la valeur de retour n'est pas capturée. Si vous voulez indiquer au compilateur que l'avertissement n'est pas nécessaire, vous ajoutez @discardableResult avant la déclaration de la méthode.

Si vous ne voulez pas utiliser la valeur de retour, vous devez explicitement informer le compilateur en l'attribuant à un trait de soulignement:

_ = someMethodThatReturnsSomething()

Motivation pour ajouter ceci à Swift 3:

  • Prévention des bogues possibles (par exemple, en utilisant sort en pensant que cela modifie la collection)
  • Intention explicite de ne pas capturer ou de devoir capturer le résultat pour d'autres collaborateurs

L'API UIKit semble être en retard sur ce point et n'ajoute pas @discardableResult pour l'utilisation parfaitement normale (sinon plus courante) de popViewController(animated:) sans capturer la valeur de retour. 

Lire la suite

494
tktsubota

Quand la vie te donne des citrons, fais une extension:

import UIKit

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

    func popToRoot(animated: Bool) {
        _ = self.popToRootViewController(animated: animated)
    }
}

Remarque que l'ajout de quelque chose comme @discardableResult func pop(animated: Bool) -> UIViewController? entraînera le même avertissement que vous essayez d'éviter.

Avec l'extension, vous pouvez maintenant écrire:

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

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

Edit: Ajouté popToRoot aussi.

38
CodeReaper

Dans Swift 3, ignorer la valeur de retour d'une fonction ayant une valeur de retour déclarée génère un avertissement.

Une façon de ne pas y participer est de marquer la fonction avec l'attribut @discardableResult. Puisque vous n'avez pas le contrôle de cette fonction, cela ne fonctionnera pas.

L'autre méthode pour se débarrasser de l'avertissement consiste à affecter la valeur à _. Cela indique au compilateur que vous savez que la méthode retourne une valeur mais que vous ne voulez pas la conserver en mémoire.

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

 Screenshot 1

Bien que ce soit work correctly if kept as it is mais le number of warning increases.

La solution consiste simplement à replace it with underscore ( _ ) même si cela semble moche.

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

 Screenshot 2

5
Jayprakash Dubey

Utilisation rejetableRésultat Dans cette condition.

Selon <Swift Programming Language>, chapitre Référence du langage - Attributs.

rejetableRésultat

Appliquez cet attribut à une déclaration de fonction ou de méthode pour supprimer l'avertissement du compilateur lorsque la fonction ou la méthode renvoyant une valeur est appelée sans utiliser son résultat.

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

Vous trouverez également une démonstration dans <Swift Programming Language>, chapitre Guide de langage - Méthodes.

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

Comme ce n’est pas nécessairement une erreur du code qui appelle la méthode advance (to :) pour ignorer la valeur de retour, cette fonction est marquée avec l’attribut @discardableResult. Pour plus d'informations sur cet attribut, voir Attributs.

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

1
black_pearl

Si vous voulez emprunter des extensions telles que la réponse de CodeReaper, vous devez utiliser @descardableResult. Cela garde toutes les possibilités, mais fait taire l'avertissement.

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
Casper Zandbergen