2015-03-30 9 views
9

Ich verstehe, was optional in Swift, aber ich begegnet nur ein „Double Wrapped Optional‘, wo, wenn ich zwei nicht '!' Xcode gibt einem complier FehlerSwift Doppel Abwickeln von Optionals

Wert von optionaler Typ 'String?' nicht ausgepackt; Wolltest du '!' oder '?'?

Ich habe den folgenden Code, wobei app vom Typ NSRunningApplication ist.

let name: String = app.localizedName! 

Warum sollte ich zwei ! verwenden? Es reicht nicht aus, die Variable auszupacken, da sie vom Typ var localizedName: String? ist.

Kontext: Xcode möchte ich let name: String = app.localizedName!! benutzen, sonst gibt es den Compiler-Fehler oben. Die app Variable wird wie folgt definiert:

var apps = NSWorkspace().runningApplications.filter{$0.activationPolicy == NSApplicationActivationPolicy.Regular} 
for app in apps{ 
    //code posted above 
    … 
} 

So weiß ich, dass app nicht optional ist und wird immer einen Wert haben, noch ist es eine optionale Anwendung.

P.S. Gibt es eine Möglichkeit, den Typ bei der schnellen Aufzählung zu definieren? Wie wo apps = [AnyObject].

+2

Wie genau ist "App" definiert? Könnte es eine * optionale * NSRunningApplication sein? –

+0

Wir stolpern um Antworten, weil diese Codezeile diesen Fehler nicht erzeugen sollte. Wenn die App optional wäre, würden Sie einen anderen Fehler erhalten. Und 'localizedName' ist kein" double optional "(lol). Diese Codezeile sieht gut aus und sollte diesen Fehler nicht generieren. Swift kann leider irreführende Fehler erzeugen, und ich frage mich, ob das eigentliche Problem in einer früheren Codezeile liegt (oder ob Sie die Codezeile bei der Vorbereitung der Frage verändert oder auf andere Weise bereinigt haben). Auch wenn ich unerklärliche Fehler bekomme, säubere ich das Projekt, beende Xcode, entleere den abgeleiteten Datenordner und starte Xcode neu. – Rob

+0

@MartinR Weitere Informationen hinzugefügt. Prost für die Hilfe. – user14492

Antwort

4

Das Problem ist, dass NSWorkspace().runningApplications gibt einen Array von AnyObject, die zu einer Reihe von NSRunningApplication gegossen werden muss:

let apps = NSWorkspace().runningApplications as! [NSRunningApplication] 
let filteredApps = apps.filter { 
     $0.activationPolicy == NSApplicationActivationPolicy.Regular 
} 
for app in apps { 
    let name: String = app.localizedName! 
} 
+0

Xcode zeigt einen Fehler für den obigen Code. Sie sollten "as" durch "as!" Ersetzen: "let apps = NSWorkspace(). RunningApplications as! [NSRunningApplication] ' – Chris

+0

@Chris: Sie haben Recht, das hat sich mit Swift 1.2 (Xcode 6.3) geändert, danke, dass Sie mich wissen lassen! –

1

Hier ist der Grund: app vom Typ AnyObject (id in Objective-C), und jede Suche auf AnyObject führt eine Ebene der Optionalität wegen der Möglichkeit, dass die Methode nicht auf dem Objekt vorhanden ist. localizedName ist selbst optional, Sie haben also zwei optionale Ebenen: die äußere Ebene ist null, wenn das Objekt nicht auf localizedName reagiert, und die innere Ebene ist null, wenn 'lokalisierterName' gleich Null ist.

Verwandte Themen