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.
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)
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:
sort
en pensant que cela modifie la collection)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.
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.
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)
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.
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.
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)
}
}