Nein, es gibt definitiv Zeiten, in denen du [unowned self]
nicht verwenden möchtest. Manchmal möchtest du, dass die Closure self
erfasst, um sicherzustellen, dass es noch vorhanden ist, wenn die Closure aufgerufen wird.
Beispiel: Durchführung einer asynchronen Netzwerkanfrage
Wenn du eine asynchrone Netzwerkanfrage durchführst, möchtest du, dass die Closure self
behält, wenn die Anfrage beendet ist. Dieses Objekt könnte sonst deallokiert worden sein, aber du möchtest immer noch in der Lage sein, die Beendigung der Anfrage zu behandeln.
Wann unowned self
oder weak self
verwenden
Die einzige Zeit, in der du wirklich [unowned self]
oder [weak self]
verwenden möchtest, ist, wenn du einen strong reference cycle erstellen würdest. Ein starker Verweiszirkel entsteht, wenn es eine Besitzschleife gibt, in der Objekte sich gegenseitig besitzen (vielleicht über einen Dritten) und daher niemals deallokiert werden, weil sie beide sicherstellen, dass der andere bestehen bleibt.
In dem spezifischen Fall einer Closure musst du nur erkennen, dass jede Variable, auf die darin referenziert wird, von der Closure "besessen" wird. Solange die Closure vorhanden ist, sind diese Objekte garantiert vorhanden. Der einzige Weg, um diesen Besitz zu stoppen, ist [unowned self]
oder [weak self]
zu verwenden. Wenn eine Klasse also eine Closure besitzt und diese Closure einen starken Verweis auf diese Klasse erfasst, hast du einen starken Verweiszirkel zwischen der Closure und der Klasse. Das gilt auch, wenn die Klasse etwas besitzt, das die Closure besitzt.
Speziell im Beispiel aus dem Video
In dem Beispiel auf der Folie besitzt TempNotifier
die Closure durch die onChange
-Instanzvariablе. Wenn sie self
nicht als unowned
deklariert hätten, würde die Closure auch self
besitzen und einen starken Verweiszirkel erstellen.
Unterschied zwischen unowned
und weak
Der Unterschied zwischen unowned
und weak
ist, dass weak
als Optional deklariert ist, während unowned
es nicht ist. Indem du es als weak
deklarierst, kannst du damit umgehen, dass es innerhalb der Closure irgendwann nil sein könnte. Wenn du versuchst, auf eine unowned
-Variable zuzugreifen, die zufällig nil ist, wird das ganze Programm abstürzen. Verwende also nur unowned
, wenn du sicher bist, dass die Variable immer vorhanden sein wird, solange die Closure vorhanden ist