ProgrammierungiOS Entwickler

Was sind die Schlüsseldifferenzen bei lazy Eigenschaften in Swift? Wann sollte man lazy verwenden, welche Besonderheiten und Fallstricke gibt es bei ihrer Initialisierung und wie kann man typische Probleme vermeiden?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

lazy Eigenschaften in Swift werden nur beim ersten Zugriff aufgerufen. Dies wird oft für ressourcenintensive Objekte verwendet (z. B. aufwändige Berechnungen, Netzwerkdownloads), die nicht sofort benötigt werden. Sie werden mit dem Schlüsselwort lazy deklariert:

class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }

Besonderheiten und Feinheiten:

  • lazy Eigenschaften sind nur für Variablen (var) erlaubt, nicht für Konstanten (let).
  • Innerhalb von Strukturen funktionieren lazy Eigenschaften nicht, wenn die Struktur selbst unveränderlich ist.
  • Wenn sie über einen anderen Thread gesetzt werden, sind sie nicht threadsicher. Man sollte gleichzeitigen Zugriff auf lazy Eigenschaften aus verschiedenen Threads vermeiden.
  • Beim Kopieren eines Klassenobjekts wird der lazy Wert für jedes Exemplar separat zwischengespeichert.

Fangfrage.

Frage: "Wird der Wert für lazy property bei der Initialisierung eines Klassenexemplars erstellt?"

Antwort: Nein, der Wert wird nur beim ersten Zugriff auf die Eigenschaft berechnet, nicht bei der Initialisierung.

class Expensive { init() { print("init") } } class Example { lazy var heavy = Expensive() } let foo = Example() // gibt nichts aus _ = foo.heavy // jetzt "init"

Beispiele für reale Fehler aufgrund fehlenden Wissens über die Feinheiten des Themas.


Geschichte

In einem plattformübergreifenden Projekt wurde ein lazy Array (lazy var) zum Speichern eines Bildcache verwendet. Bei gleichzeitigem Zugriff aus mehreren Threads traten Rennbedingungen auf, sie umschlossen lazy var mit Mutexen — vergaßen jedoch den lazy, was zu einem Absturz der Anwendung führte.


Geschichte

Ein junger Entwickler versuchte, lazy let zu deklarieren, um eine aufwändige Berechnung zu cachen. Der Code ließ sich nicht kompilieren, da lazy nur für var erlaubt ist: Sie mussten die Architektur überdenken.


Geschichte

Der Entwickler deklarierte eine lazy property mit dem Einfangen von self innerhalb einer Closure bei der Initialisierung. Dies führte zu einer zyklischen Referenz — das Objekt wurde nicht deinitialisiert, selbst nachdem es von allen Bildschirmen entfernt wurde.