Blog

Einschneidende Änderungen in Swift 4

Bart den Hollander

Bart den Hollander

Aktualisiert Oktober 21, 2025
5 Minuten
In diesem Blog möchte ich Ihnen einen Einblick in die zahlreichen Änderungen geben, die mit Swift 4 eingeführt werden. Außerdem zeige ich Ihnen, wie Sie bereits mit Swift 4 im aktuellen Xcode 8.3.2 arbeiten können.

Wechselnde Änderungen

Wenn wir alle umgesetzten Swift 4 Vorschläge zusammenfassen würden, kämen wir (Stand 31.5.17) auf die folgende Liste.

Die fett hervorgehobenen Vorschläge sind Vorschläge, die Änderungen am Quellcode von Swift 4 vorsehen. Sehen wir uns jeden dieser Vorschläge genauer an.

Unterscheidung zwischen Funktionstypen mit einem Tupel und mehreren Argumenten "Š-"Š(SE-0110)

Mit diesem Vorschlag müssen Sie nun Tupel aus dem nun einzigen Parameter manuell erweitern. Lassen Sie es uns anhand eines Beispiels erklären.

typealias Name = (vorname: String, nachname: String)
let names: [Name] = [("Bart", "den Holländer")]
Ich habe ein Tupel innerhalb eines Arrays deklariert. Jetzt möchte ich eine Schleife über jedes Tupel im Array laufen lassen und den Nachnamen ausgeben. Lassen Sie uns dies in Swift 3 tun.
// Swift 3
names.forEach({ first, last in
  print(last)  // "den Holländer"
})

Die Variablen 'first' und 'last' werden vom Swift 3 Compiler aus dem Tupel erweitert. Das ist sehr hilfreich und lesbar. Lassen Sie uns nun dasselbe in Swift 4 tun.

// Swift 4
names.forEach({ first, last in
  print(last)
})
// Fehler: Closure-Tupel-Parameter '(vorname: String, nachname: String)' unterstützt keine Destrukturierung

Der Grund dafür, dass dies nicht mehr funktioniert, ist, dass Sie in Swift 4 Tupel manuell aus einem einzelnen Parameter erweitern müssen. Sie können dies folgendermaßen beheben.

// Swift 4
A: Erweitern Sie durch Angabe des Tupelschlüssels
names.forEach({ name in
  print(name.lastName)  // "den Holländer"
})
B: Erweitern durch Angabe der Anzahl der Tupel-Elemente in einer Variablen
names.forEach({ name in
  let (Vorname, Nachname) = Name
  print(last)  // "den Holländer"
})
C: Wechsel zu einer for-Schleife
for (vor, nach) in Namen {
  print(last)  // "den Holländer"
}

Dennoch wird die Frage aufgeworfen, warum diese Änderung eingeführt wurde. Diese Frage wird von Joe Groff, Swift Compiler Engineer bei Apple, beantwortet.

https://twitter.com/jckarter/status/867750246935216128

Ich denke, dass diese Änderung zwar zu einer besseren Leistung des Typprüfers führt, aber auch zu einer schlechteren Lesbarkeit der Syntax.


Begrenzung der @objc Inferenz "Š-"Š(SE-0160)

In Swift 3 galt für die Anmerkung @objc die folgende Faustregel.

Um in Objective-C zugänglich und verwendbar zu sein, muss eine Swift-Klasse ein Nachkomme einer Objective-C-Klasse sein oder sie muss als @objc gekennzeichnet sein.

Das bedeutet, dass Sie Ihre Swift-Klasse in NSObject umwandeln müssen und jede Eigenschaft dieser Klasse dann vom Swift 3-Compiler mit @objc annotiert wird. Dasselbe gilt für die Verwendung von #selector in Swift, da sie mit Objective-C unter Wasser arbeiten.

Mit diesem Vorschlag müssen Sie nun jede Eigenschaft einer Swift-Klasse, die in Objective-C verwendet wird, manuell mit @objc annotieren, damit der Compiler effizienter arbeiten kann. Ein einfaches Beispiel für das Hinzufügen dieser Annotation, bei dem foo() in Objective-C zugänglich ist, ist das folgende.

Klasse Super {
  @objc
  func foo() { }
}

Hinweis: Ein Migrationsplan ist in diesem Vorschlag enthalten diesem Vorschlag. Dieser Plan bietet einen 3-stufigen Arbeitsablauf, der bei einigen Projekten hilfreich sein kann.


Verbesserung der Interaktion zwischen private Deklarationen und Erweiterungen "Š-"Š(SE-0169)

SE-0169 ändert erneut die Regeln für die Zugriffskontrolle. Diesmal werden die Zugriffskontrollregeln für private und fileprivate in Kombination mit der Verwendung einer Erweiterung geändert. In Swift 4 können wir nun die Zugriffsebene private bereitstellen, um sie für eine Erweiterung desselben Typs zugänglich zu machen. Lassen Sie uns dies anhand von Beispielen erklären.

In Swift 3 könnten Sie das folgende Programm haben.

struct Niederlande {
  private var languages = ["Niederländisch"]
}
Verlängerung Niederlande {
  mutating func add(language: String) {
  languages.append(Sprache)
}
// Fehler: 'Sprachen' ist aufgrund der Schutzstufe 'privat' nicht zugänglich

Der Fehler besagt, dass die Zugriffsebene private der Erweiterung den Zugriff auf languages verwehrt. Das ist seltsam, denn wenn Sie eine Erweiterung für den gleichen Typ erstellen, sollte der Zugriff auf languages möglich sein.

In Swift 4 ist dies behoben und languages ist über eine Erweiterung mit private zugänglich. 🎉.

Die bahnbrechende Änderung in diesem Vorschlag entsteht, wenn es private Eigenschaften mit der gleichen Signatur im gleichen Typ/Erweiterung, aber in verschiedenen Bereichen gibt. Es würde dann ein Invalid redeclaration of 'signatureX' Fehler auftreten. Eine Änderung der Signatur würde dieses Problem beheben.

Aktuelle Codebasis

Wäre es möglich, dass ich meine aktuelle Codebasis bereits mit den Änderungen in Swift 4 vergleichen kann? Ja, das können Sie!

Sie müssen nur den neuesten Swift 4.0 Snapshot herunterladen und installieren und den installierten Snapshot im Toolchain-Menü in Xcode auswählen. Die folgende Abbildung zeigt, wo sich das Toolchain-Menü befindet.

Toolchain in Xcode

Wenn die Toolchain geändert wurde, können Sie nun Ihr Projekt starten und versuchen, es mit dem Snapshot zu erstellen!

Ein Snapshot ist natürlich nicht die endgültige Version, aber es sind bereits viele Vorschläge implementiert, von denen Sie eine grobe Schätzung des Arbeitsaufwands erstellen können, der auf Sie zukommt. Auf diese Weise wissen Sie, welche Auswirkungen diese neue Swift-Version auf Ihre bestehende Codebasis haben wird.

Danke fürs Lesen!

Folgen Sie mir auf Twitter, um über neue Blogs informiert zu werden.

Verfasst von

Bart den Hollander

Contact

Let’s discuss how we can support your journey.