ARC (Automatic Reference Counting) ist ein System zur automatischen Speicherverwaltung in Swift. Bei jedem neuen starken Verweis auf ein Objekt wird der Zähler erhöht; bei dessen Entfernen verringert. Wenn der Zähler null erreicht, wird das Objekt freigegeben.
Retain Cycle (Haltenzyklus) ist eine Situation, in der Objekte sich gegenseitig durch starke Referenzen aufrechterhalten und niemals freigegeben werden.
Methoden zur Vermeidung:
protocol SomeDelegate: AnyObject { } class Owner { weak var delegate: SomeDelegate? }
[weak self] oder [unowned self]:class Example { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doSomething() } } func doSomething() { } }
Was ist der Unterschied zwischen [weak self] und [unowned self] innerhalb eines Closures? Welchen Typ von Referenzen sollte man verwenden und wann?
Antwort:
[weak self] erstellt eine optionale Referenz; self kann nil sein, daher wird normalerweise sicheres Entpacken self? verwendet.[unowned self] erstellt eine nicht-optionale Referenz und erhöht den Zähler NICHT; wenn das Objekt bereits freigegeben wurde und ein Zugriff erfolgt, wird es zum Crash führen.[unowned self] verwendet werden.Beispiel:
someClosure = { [weak self] in self?.doTask() } // oder (wenn self 100% länger lebt als das Closure): someClosure = { [unowned self] in doTask() }
Geschichte
Im Projekt ergab sich eine Situation eines Retain-Cycles zwischen ViewController und seinem Closure, das mit der Behandlung von Tasteneingaben verknüpft war. Der ViewController verwies auf das Closure, das self mit einer starken Referenz erfasste. In der Folge wurden der Controller und alle seine Daten nach dem Schließen des Bildschirms nicht freigegeben. Das Problem wurde durch die Implementierung von [weak self] im Closure gelöst.
Geschichte
Implementierung des Delegatemusters zwischen zwei Objekten. Der Delegate wurde als stark (
strong) Eigenschaft deklariert. In der Folge wurde das Hauptobjekt beim Versuch, es aus dem Speicher zu entfernen, nicht dealloziert, was zu einem Speicherleck führte. Nach der Änderung des Delegates auf weak verschwand das Problem.
Geschichte
Für Animationen wurde ein Closure innerhalb von UIView verwendet. Das Closure erfasste self mit
[unowned self]. Als die Views vor Abschluss der Animation entfernt wurden, stürzte die Anwendung ab, da auf das bereits freigegebene self zugegriffen wurde. Lösung — Verwendung von[weak self]und zwingende Überprüfung auf nicht-nil self innerhalb des Closures.