Weak Reference — was es ist, Syntax und Verwendung in der mobilen Entwicklung

Autor: IT Sectr Veröffentlicht: 2026-03-30 Lesezeit: 9 Min.

Weak Reference (schwache Referenz) ist ein Verweis auf ein Objekt, der dessen Retain Count in ARC nicht erhöht. Laut Apple Swift Language Guide, 2026 werden schwache Referenzen mit dem Schlüsselwort weak deklariert und sind immer optional. Wenn das Objekt freigegeben wird, werden alle schwachen Referenzen darauf automatisch auf nil gesetzt, was hängende Zeiger verhindert und schwache Referenzen zu einem sicheren Mechanismus zum Auflösen von Retain Cycles macht.

Wichtigste Punkte

  • Weak Reference — ein Verweis, der den Retain Count des Objekts nicht beeinflusst; wird bei Freigabe des Objekts nil
  • Deklaration — das Schlüsselwort weak vor var; Typ ist immer optional (?)
  • Verwendung — Delegaten, Closures, Eltern-Kind-Beziehungen zum Auflösen von Retain Cycles
  • Sicherheit — automatisches Setzen auf nil nach der Freigabe des Objekts (zeroing weak)
  • Unterschied zu unowned — weak wird nil und ist sicher, unowned wird nicht nil und erfordert Lebensdauergarantien

Was ist Weak Reference?

Weak Reference ist ein nicht-besitzender Verweis auf ein Objekt in ARC (Automatic Reference Counting). Im Gegensatz zu einer starken Referenz, die den Retain Count des Objekts erhöht und seine Lebensdauer garantiert, erlaubt eine schwache Referenz, dass das Objekt freigegeben wird, selbst wenn noch darauf verwiesen wird. Nach der Freigabe wird die schwache Referenz automatisch auf nil gesetzt — dies wird als zeroing weak bezeichnet.

Zeroing weak ist eine Schlüsselfunktion der Swift- und Objective-C-Laufzeitumgebung. Wenn der Referenzzähler eines Objekts Null erreicht und das Objekt freigegeben wird, durchläuft die Laufzeitumgebung alle schwachen Referenzen auf dieses Objekt (gespeichert in einer speziellen Weak-Tabelle) und setzt sie auf nil. Dies stellt sicher, dass der Zugriff auf freigegebenen Speicher (Use-after-free) über schwache Referenzen unmöglich ist — jeder Lesezugriff gibt nil zurück.

Laut Apple WWDC 2012 Session 406 haben Zeroing-Weak-Referenzen eine ganze Klasse von Absturzfehlern im Zusammenhang mit hängenden Zeigern (Dangling Pointers) beseitigt, die in der manuellen Speicherverwaltung (MRR) üblich waren. In MRR existierten schwache Referenzen nur als __unsafe_unretained — sie wurden nicht genullt, und der Zugriff auf ein freigegebenes Objekt führte zu EXC_BAD_ACCESS.

Weak-Syntax in Swift und Objective-C

Betrachten wir die Syntax zum Deklarieren schwacher Referenzen in beiden Sprachen des Apple-Ökosystems. Trotz der gemeinsamen Laufzeitumgebung unterscheidet sich die Syntax, aber die Semantik ist identisch.

Swift

In Swift werden schwache Referenzen mit dem Schlüsselwort weak vor var deklariert. Der Typ muss immer optional sein (Typ?), da die Referenz jederzeit nil werden kann. Konstanten (let) können nicht weak sein — nur Variablen.

swift
class ViewController: UIViewController {
    // weak properties: only var, only optional
    weak var delegate: ViewControllerDelegate?
    weak var parentView: UIView?

    weak var completionHandler: ((Bool) -> Void)?  // ⚠️ Closures speichern weak nicht
    // ⬆️ Fehler: weak kann nur auf Klassentypen angewendet werden, nicht auf Closures
}

Wichtig: weak ist nur auf Klasseninstanzen (Klassentypen), AnyObject und von AnyObject abgeleitete Protokolle anwendbar. Struct, Enum und Closures können nicht weak sein — sie sind Wertetypen und nehmen nicht an ARC teil.

Objective-C

In Objective-C werden schwache Eigenschaften mit dem Attribut __weak oder dem Modifikator weak in Eigenschaftsdeklarationen deklariert:

objective-c
// Objective-C: weak property
@interface MyViewController : UIViewController
@property (weak, nonatomic) id<MyDelegate> delegate;
@end

// Lokale weak-Variable
__weak MyObject *weakRef = someStrongObject;

Die Objective-C-Laufzeitumgebung bietet ebenfalls zeroing weak, blockiert jedoch zusätzlich die Verwendung von weak mit C-Strukturen und einigen Core Foundation-Objekten. Für diese wird __unsafe_unretained verwendet — ohne Zeroing.

Wann man schwache Referenzen verwendet

Schwache Referenzen sind keine universelle Lösung, sondern ein Werkzeug für bestimmte Szenarien. Die überall Verwendung von weak führt zu unnötiger Komplexität und beeinträchtigt die Lesbarkeit. Betrachten wir die richtigen Anwendungsszenarien.

Delegaten (Delegate-Pattern)

Delegaten — das primäre Szenario für weak. Das besitzende Objekt (z. B. UITableView) hält eine starke Referenz auf sich selbst, während der Delegat (UIViewController) die Tabelle nicht besitzen sollte. Das Apple SDK garantiert, dass alle Delegaten und dataSources weak sind. Verwenden Sie für Ihre eigenen Protokolle immer weak var delegate.

Eltern-Kind mit Rückverweis

Wenn ein Kindobjekt auf sein Elternobjekt verweisen muss (z. B. ChildViewController, der auf einen Koordinator zugreift), verwenden Sie eine schwache Referenz. Das Elternteil besitzt das Kind (strong), das Kind beobachtet das Elternteil (weak) — der Retain Cycle ist eliminiert.

Asynchrone Closures

Capture List [weak self] — die Standardmethode, um Retain Cycles in Closures zu vermeiden, die als Klasseneigenschaften gespeichert werden. Wenn self vor Abschluss der Closure freigegeben werden kann, ist weak self obligatorisch.

SzenarioWeakStrong
Delegate✅ Immer weak❌ Retain Cycle
Eltern → Kind❌ Nicht nötig (Eltern sollten besitzen)✅ Strong
Kind → Eltern✅ Weak❌ Retain Cycle
Asynchroner Callback✅ [weak self]❌ Retain-Cycle-Risiko
Starke Kopplung (owned)❌ unowned✅ Strong

Allgemeine Regel: Wenn Objekt A B besitzt (A → B strong), dann sollte B → A weak oder unowned sein. Die Richtung der starken Referenzen sollte immer vom Besitzer zum Untergebenen sein.

Weak vs Unowned: Vergleich und Szenarien

Sowohl weak als auch unowned erhöhen den Retain Count nicht, unterscheiden sich jedoch im Verhalten nach der Freigabe des Objekts. Die Wahl zwischen ihnen ist eine Frage der Lebensdauergarantien.

Unterschiede

Weak: wird automatisch nil, Typ ist immer optional, erfordert Entpacken vor der Verwendung. Sicher — Zugriff auf nil verursacht keinen Absturz.

Unowned: wird nicht nil, Typ ist nicht optional. Wenn das Objekt freigegeben wird, wird eine unowned-Referenz zu einem hängenden Zeiger — der Zugriff darauf verursacht einen Laufzeitabsturz. Unowned geht davon aus, dass das Objekt mindestens so lange lebt wie die referenzierende Seite.

Wann man weak wählt

Wählen Sie weak, wenn: das Objekt jederzeit freigegeben werden kann (Delegat nach Schließen des Bildschirms), Sie die Lebensdauer des Objekts nicht kontrollieren oder Sie sich bei den Garantien unsicher sind. Weak ist die universelle sichere Wahl.

Wann man unowned wählt

Wählen Sie unowned, wenn: das Objekt garantiert nicht vor dem referenzierenden Objekt freigegeben wird (z. B. Kunde → Kreditkarte, wo die Karte ohne den Kunden nicht existiert). Unowned bietet eine nicht-optionale API ohne Entpacken, was im Code bequemer ist.

swift
class Order {
    let id: Int
    var items: [Item] = []

    init(id: Int) { self.id = id }

    // Starke Beziehung: Order besitzt Item
    func addItem(name: String) {
        let item = Item(name: name, order: self)
        items.append(item)
    }
}

class Item {
    let name: String
    unowned let order: Order          // ✅ unowned — Item lebt nicht ohne Order

    init(name: String, order: Order) {
        self.name = name
        self.order = order
    }
}

// Beispiel mit weak: Delegat ohne Lebensdauergarantie
protocol NetworkServiceDelegate: AnyObject {
    func didReceiveResponse(data: Data)
}

class NetworkService {
    weak var delegate: NetworkServiceDelegate?  // ✅ weak — Delegat kann verschwinden
}

Im Beispiel verwendet Item unowned, weil ein Bestellposten ohne die Bestellung selbst nicht existieren kann — die Lebensdauergarantie ist eisern. NetworkService verwendet weak, weil der Delegat (z. B. ViewController) jederzeit geschlossen und freigegeben werden kann.

Einschränkungen und Fallstricke schwacher Referenzen

Schwache Referenzen sind ein leistungsstarkes Werkzeug, haben aber Einschränkungen, die für die korrekte Verwendung in der iOS-Entwicklung wichtig zu verstehen sind.

Weak-Leistung

Schwache Referenzen sind langsamer als starke: Bei jedem Zugriff prüft die Laufzeitumgebung, ob das Objekt freigegeben wurde (Lookup in der Weak-Tabelle). In den allermeisten Szenarien ist der Unterschied nicht spürbar, aber in heißen Schleifen mit Millionen von Zugriffen kann weak zum Engpass werden. Verwenden Sie für Hochlastszenarien strong und reorganisieren Sie die Architektur.

Weak ist nicht auf Wertetypen anwendbar

Struct, Enum, Tuple — Wertetypen, die nicht an ARC teilnehmen. Der Versuch, ein weak struct zu deklarieren, führt zu einem Kompilierungsfehler. Um eine schwache Referenz auf einen Wertetyp zu speichern, verwenden Sie einen Wrapper in einem Klassentyp oder eine Closure.

Weak in Multithreading

Zeroing weak ist threadsicher: Wenn ein Objekt in einem Thread freigegeben wird, wird die schwache Referenz in allen Threads atomar genullt. Das Fenster zwischen dem Lesen einer schwachen Referenz und dem Dereferenzieren kann jedoch zu einer Wettlaufsituation führen — das Objekt wird zwischen dem Erhalten der schwachen Referenz und ihrer Verwendung freigegeben. Lösung: Strong Capture der schwachen Referenz in eine lokale Variable.

swift
// Race Condition mit weak in Multithreading
func performAsync() {
    weak var weakSelf = self
    queue.async {
        // ⚠️ weakSelf kann zwischen Prüfung und Verwendung nil sein
        if weakSelf != nil {
            weakSelf!.doSomething()  // CRASH wenn nil wird
        }
    }
}

// ✅ Korrektur: starker Capture während der Verwendung
func performAsyncSafe() {
    queue.async { [weak self] in
        guard let strongSelf = self else { return }
        strongSelf.doSomething()  // strongSelf — lokale starke Referenz
    }
}

In der sicheren Version wird weak self erfasst und dann sofort in eine lokale starke Variable strongSelf entpackt. Wenn self noch lebt, bleibt es für die Dauer des Blocks am Leben. Wenn nicht, wird guard ausgelöst und der Code wird nicht ausgeführt. Dieses Idiom ist das Standardmuster für asynchrone Closures in Swift.

UIView und Weak Outlets

IBOutlet in Interface Builder sollten weak sein, da die Ansichtshierarchie bereits eine starke Referenz auf die Unteransicht hält. Das Duplizieren einer starken Referenz im Controller erzeugt keinen Retain Cycle, ist aber redundant. Eine schwache Referenz auf ein Outlet ist Apples Empfehlung, obwohl viele Entwickler aus Gründen der Code-Einfachheit strong verwenden.

Häufig gestellte Fragen

Kann eine schwache Referenz auf ein Objekt zeigen, das noch nicht erstellt wurde?

Nein, weak kann nur auf ein vorhandenes Objekt oder nil zeigen. Beim Erstellen eines neuen Objekts erhalten Sie zunächst eine starke Referenz (über einen Initialisierer), und erst dann können Sie eine schwache Referenz zuweisen. Ein weak nil am Anfang ist ein normaler Zustand.

Warum funktioniert weak nur mit Klassentypen?

Weak basiert auf ARC, das nur Referenztypen (Klassen) verwaltet. Wertetypen (struct, enum) werden bei der Zuweisung kopiert und haben keinen Retain Count. Für schwache Beziehungen mit Wertetypen verwenden Sie Closures oder Wrapper in einer Klasse mit einer weak-Eigenschaft.

Wie wirkt sich weak auf die Leistung in einer Schleife aus?

Jeder Zugriff auf eine schwache Referenz führt einen Lookup in der Laufzeittabelle durch. In einer Schleife mit Millionen von Iterationen kann dies 2–5 Mal langsamer sein als eine starke Referenz. Kopieren Sie für heiße Pfade weak vor der Schleife in eine lokale starke Variable.

Wann kann eine schwache Referenz unerwartet nil werden?

Wenn alle starken Referenzen auf das Objekt verloren gehen — am Ende des Gültigkeitsbereichs, beim Neuzuweisen einer Eigenschaft oder beim Schließen eines Bildschirms. In einer Multithread-Umgebung kann dies zwischen zwei Codezeilen passieren. Überprüfen Sie schwache Referenzen immer mit guard let oder if let.

Wie unterscheidet sich weak von __weak in Objective-C?

Semantisch identisch: beide bieten zeroing weak. Unterschiede: Swift erfordert einen optionalen Typ und var, Objective-C verwendet einen Eigenschaftsmodifikator. Objective-C unterstützt auch __unsafe_unretained — eine schwache Referenz ohne Zeroing (Risiko eines hängenden Zeigers).

Zusammenfassung

  • Weak Reference — ein nicht-besitzender Verweis, der den Retain Count nicht erhöht und bei Freigabe automatisch genullt wird
  • Syntaxweak var + optionaler Typ; nur Klassentypen und AnyObject-Protokolle
  • Zeroing weak — Laufzeitumgebung nullt alle schwachen Referenzen auf ein freigegebenes Objekt und verhindert so hängende Zeiger
  • Szenarien — Delegaten, Eltern-Kind mit Rückverweis, asynchrone Closures ([weak self])
  • Weak vs Unowned — weak wird nil (sicher), unowned wird nicht nil (Absturzrisiko, aber nicht optional)
  • Leistung — weak ist aufgrund des Lookups in der Laufzeittabelle langsamer als strong; für heiße Pfade in strong kopieren
  • Empfehlung — wenn Sie sich bei Lebensdauergarantien unsicher sind, wählen Sie weak

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch