web-dev-qa-db-de.com

Xcode 8/Swift 3: Warnung "Ausdruck des Typs UIViewController? Wird nicht verwendet"

Ich habe die folgende Funktion, die zuvor sauber kompiliert wurde, aber mit Xcode 8 eine Warnung generiert.

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

Msgstr "Ausdruck des Typs" UIViewController? "Wird nicht verwendet".

Warum sagt es das und gibt es eine Möglichkeit, es zu entfernen?

Der Code wird wie erwartet ausgeführt.

226
Gruntcakes

TL; DR

popViewController(animated:) gibt UIViewController? zurück, und der Compiler gibt diese Warnung aus, da Sie den Wert nicht erfassen. Die Lösung besteht darin, es einem Unterstrich zuzuordnen:

_ = navigationController?.popViewController(animated: true)

Swift 3 Change

Vor Swift 3 hatten alle Methoden standardmäßig ein "verwerfbares Ergebnis". Es wird keine Warnung angezeigt, wenn Sie nicht erfasst haben, was die Methode zurückgegeben hat.

Um dem Compiler mitzuteilen, dass das Ergebnis erfasst werden soll, mussten Sie vor der Methodendeklaration @warn_unused_result hinzufügen. Es würde für Methoden verwendet, die eine veränderliche Form haben (zB sort und sortInPlace). Sie würden @warn_unused_result(mutable_variant="mutableMethodHere") hinzufügen, um den Compiler davon zu informieren.

Bei Swift 3 wird das Verhalten jedoch umgekehrt. Alle Methoden warnen nun, dass der Rückgabewert nicht erfasst wird. Wenn Sie dem Compiler mitteilen möchten, dass die Warnung nicht erforderlich ist, fügen Sie vor der Methodendeklaration @discardableResult hinzu.

Wenn Sie den Rückgabewert nicht verwenden möchten, müssen Sie dem Compiler explizit mitteilen, indem Sie ihn einem Unterstrich zuordnen:

_ = someMethodThatReturnsSomething()

Motivation für das Hinzufügen von Swift 3:

  • Vorbeugung möglicher Fehler (z. B. mit sort, da sie die Auflistung ändert)
  • Explizite Absicht, das Ergebnis für andere Mitarbeiter nicht zu erfassen oder zu erfassen

Die UIKit-API scheint diesbezüglich hinterherzugehen und fügt @discardableResult nicht für die ganz normale (wenn auch nicht üblichere) Verwendung von popViewController(animated:) hinzu, ohne den Rückgabewert zu erfassen. 

Weiterlesen

494
tktsubota

Wenn das Leben Ihnen Zitronen gibt, machen Sie eine Erweiterung:

import UIKit

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

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

Hinweis Wenn Sie etwas wie @discardableResult func pop(animated: Bool) -> UIViewController? hinzufügen, wird dieselbe Warnung angezeigt, die Sie vermeiden möchten.

Mit der Erweiterung können Sie jetzt schreiben:

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

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

Bearbeiten: PopToRoot hinzugefügt.

38
CodeReaper

In Swift 3 führt das Ignorieren des Rückgabewerts einer Funktion mit deklariertem Rückgabewert zu einer Warnung.

Eine Möglichkeit, dies zu deaktivieren, ist das Markieren der Funktion mit dem @discardableResult-Attribut. Da Sie keine Kontrolle über diese Funktion haben, funktioniert das nicht.

Die andere Methode zum Entfernen der Warnung besteht darin, den Wert _ zuzuweisen. Dies teilt dem Compiler mit, dass die Methode einen Wert zurückgibt, der jedoch nicht im Speicher verbleiben soll.

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

 Screenshot 1

Obwohl es work correctly if kept as it is aber der number of warning increases.

Die Lösung ist einfach replace it with underscore ( _ ), obwohl es hässlich zu sein scheint.

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

 Screenshot 2

5

Benutzen discardableResult in diesem Zustand.

Gemäß <Swift Programming Language>, Kapitel Sprachreferenz - Attribute.

discardableResult

Wenden Sie dieses Attribut auf eine Funktions- oder Methodendeklaration an, um die Compiler-Warnung zu unterdrücken, wenn die Funktion oder Methode, die einen Wert zurückgibt, ohne Verwendung des Ergebnisses aufgerufen wird.

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

Es gibt auch eine Demo in <Swift Programming Language>, Kapitel Sprachanleitung - Methoden.

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

Da es nicht unbedingt ein Fehler für Code ist, der die Methode advance (to :) zum Ignorieren des Rückgabewerts aufruft, wird diese Funktion mit dem Attribut @discardableResult gekennzeichnet. Weitere Informationen zu diesem Attribut finden Sie unter Attribute.

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

1
black_pearl

Wenn Sie Erweiterungen wie die Antwort von CodeReaper nutzen möchten, sollten Sie @descardableResult verwenden. Dadurch bleiben alle Möglichkeiten erhalten, die Warnung wird jedoch zum Schweigen gebracht.

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