2017-01-04 2 views
0

Ich beginne gerade mit der Arbeit an einem Projekt, und meine erste Aufgabe ist das Zerlegen eines God Objects, das jemand anderes aus dem AppDelegate erstellt hat. Ich habe damit begonnen, Code zu kopieren, der sich auf die Verwaltung des Standortes bezieht, um Aufrufe an diesen Code in das neue Objekt zu delegieren.Warum würde identischer Code an einer Stelle einen Fehler ausgeben, aber nicht an einer anderen Stelle?

Ich habe zwei Aussagen, die mich aber verrückt machen.

Neue Datei:

if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...} 

Alt-Datei:

if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...} 

Sie sind der Code bemerken identisch ist. In beiden Fällen self.locationManager? wie folgt definiert ist:

var locationManager: CLLocationManager? 

Aber in der neuen Datei, erhalte ich eine Warnung über ‚Wert des optionalen Typs keine ungeöffneten‘ - warum? Exakter doppelter Code, kopiert & eingefügt, was würde das anders machen?

den Code ändern es auszupacken behebt Dinge:

if (locationManager?.location?.horizontalAccuracy)! > horizontalAccuracyCheck{...} 

ich um meinen Kopf wickeln kann, warum ich brauche, um explizit eine potenziell optional Rück auspacken. Aber ... warum nur an einem Ort?

+1

Meine Vermutung ist, dass der Migrator [http://stackoverflow.com/q/39251005/2976878] für optionale Vergleich in der alten Datei eingefügt, aber es ist nicht ein in der neuen Datei (Ich glaube nicht * Sie können Swift 2 und Swift 3 zusammen auf dem gleichen Ziel mischen). – Hamish

+0

@Hamish sollten Sie das als Antwort geben. Wenn es richtig ist, ist es eine brillante Schätzung und verdient es offensichtlich, die akzeptierte Antwort zu sein. – matt

+0

D'oh. @ Hamish ist fast sicher korrekt - die Überladung ist in der älteren Datei vorhanden. Es ist auf meiner To-Do-Liste, um es irgendwann zu entfernen. – RonLugge

Antwort

2

Wie in this Q&A diskutiert - der Swift Migrator wird eine benutzerdefinierte fileprivate Operator einfügen Überladen, um optionale Vergleiche in Swift 3 wie in Swift 2 zu ermöglichen. Da diese Überladung fileprivate ist, können Sie sie aus anderen Quelldateien in Ihrem Projekt nicht verwenden Definieren Sie es, weshalb Ihr Vergleich in der neuen Quelldatei nicht kompiliert werden kann.

Daher ist eine Lösung nur, um es in Ihre neue Datei zu kopieren. Eine weitere Möglichkeit besteht darin, den Zugriffsmodifikator fileprivate zu entfernen. Die Überladung wird standardmäßig auf internal festgelegt und ist daher für andere Swift-Dateien in Ihrem Modul verfügbar.

Obwohl wirklich würde ich nur empfehlen, die Überlastung vollständig zu entfernen und stattdessen Ihre eigene explizite Logik für optionalen Vergleich zu schreiben, wenn es auftritt - die Überlastung kann zu leicht missbraucht werden (wie durch die Swift evolution proposal gezeigt, um es zu entfernen).

+0

Die Entfernung des Modifikators ist auf meiner To-Do-Liste, ich habe gerade nicht die Punkte zwischen 'ja, das sagt, es sollte entfernt werden, so lass es uns bald tun' und meinem aktuellen Problem. – RonLugge

+0

Erstaunlich. Ich hatte keine Ahnung, dass der Migrator das getan hat. Jetzt muss ich meinen eigenen Code suchen, um sicherzugehen, dass es mir nicht ähnlich ist! – matt

3

Der Grund ist, dass wir hier über zwei ziemlich verschiedene Sprachen sprechen. Eine Datei ist Swift 2, die andere Datei ist Swift 3. In Swift 2 können Sie eine Option, die eine Zahl mit einer anderen Zahl vergleicht, mit dem Operator "Größer als" oder "Kleiner als" vergleichen.

. In Swift 3 können Sie das nicht tun.

Hier ist ein einfacheres Beispiel für die gleiche Sache:

let optint : Int? = 7 
    let ok = optint < 42 

Dieser Code ist legal in Swift 2, aber illegal in Swift 3.

+0

Sie sagen, dass das * gleiche Projekt * sowohl in Swift2 als auch in Swift3 sein kann? Interessant. – RonLugge

+0

Meine Vermutung ist, dass Sie dieses Projekt geerbt haben, nachdem es in Xcode 8 und damit in Swift 3 migriert wurde. Die Migration kann für ein Ziel, aber nicht für ein anderes durchgeführt werden. Auch mehrere Schemata können das Bild komplizieren. Plus mein Gedächtnis ist, dass wenn Migration _first_ stattfindet, Sie sogar auf einer Datei pro Datei migrieren können (Info über das wird in der Projektdatei behalten, wo Sie es nicht sehen können). Ich müsste das Projekt sehen, um besser abschätzen zu können, wie diese Situation zustande kam. Aber meine Vermutung ist, dass diese Dateien nie zu Swift 3 migriert wurden, aber Ihre neue Datei ist standardmäßig in Swift 3. – matt

+0

Im wörtlichen Sinne bin ich derjenige, der es migriert hat. Dafür wurde ich ursprünglich an Bord geholt - und die neue Datei wurde nach der Migration erstellt. – RonLugge

Verwandte Themen