Sollen wir in Swift immer das [unbenannte Selbst] innerhalb des Verschlusses benutzen
In der WWDC 2014 session 403 Intermediate Swift und transcriptgab es die folgende Folie
Der Sprecher sagte, in diesem Fall, wenn wir nicht verwenden [unowned self]
es, es wird ein memory-leak. Bedeutet es, wir sollten immer [unowned self]
innen Verschluss?
Auf Zeile 64 der ViewController.swift der Swift-Wetter-appich glaube nicht, verwenden [unowned self]
. Aber ich update die Benutzeroberfläche mit einigen @IBOutlet
s wie self.temperature
und self.loadingIndicator
. Es kann OK sein, weil alle @IBOutlet
s I definiert sind weak
. Aber zur Sicherheit sollten wir immer [unowned self]
?
class TempNotifier {
var onChange: (Int) -> Void = {_ in }
var currentTemp = 72
init() {
onChange = { [unowned self] temp in
self.currentTemp = temp
}
}
}
InformationsquelleAutor der Frage Jake Lin | 2014-06-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, es gibt definitiv Zeiten, in denen Sie nicht wollen, zu verwenden
[unowned self]
. Manchmal möchte man die Schließung zu erfassen, selbst in, um sich zu vergewissern, dass es noch rund um die Zeit der Stilllegung genannt.Beispiel: einem asynchronen Netzwerk-Anfrage
Wenn Sie eine asynchrone Netzwerk-Anfrage Sie tun wollen die Schließung zu bewahren
self
wenn die Anfrage beendet ist. Das Objekt kann sonst freigegeben, aber Sie wollen immer noch in der Lage, die Anforderung zu verarbeiten finishing.Wann
unowned self
oderweak self
Das einzige mal, wo Sie wirklich wollen, verwenden Sie
[unowned self]
oder[weak self]
ist, wenn Sie schaffen würde,starke Referenz-Zyklus. Eine starke Referenz-Zyklus ist, wenn es eine Schleife von Eigentum, wo die Objekte am Ende der Besitz jeder andere (vielleicht durch einen Dritten), und daher werden Sie nie freigegeben, weil Sie beide sicherstellen, dass jede andere Stock herum.In dem speziellen Fall, dass eine Schließung, die Sie gerade brauchen, um zu realisieren, dass jede variable, auf die verwiesen wird im inneren erhält "Besitz" von der Schließung. Solange der Verschluss ist rund, diese Objekte werden garantiert, um ringsherum zu sein. Der einzige Weg zu stoppen, dass das Eigentum, ist das
[unowned self]
oder[weak self]
. Also, wenn eine Klasse besitzt einen Verschluss, so dass diese Schließung zeigt eine starke Referenz auf die Klasse, dann haben Sie eine starke Referenz-Zyklus zwischen dem Verschluss und der Klasse. Dies beinhaltet auch wenn die Klasse besitzt etwas, besitzt die Schließung.Speziell in dem Beispiel aus dem video
In dem Beispiel auf der Folie
TempNotifier
besitzt die Schließung durch dieonChange
member-Variablen. Wenn Sie sich nicht erklärenself
alsunowned
die Schließung würde auch die eigenenself
Schaffung einer starken Referenz-Zyklus.Unterschied zwischen
unowned
undweak
Den Unterschied zwischen
unowned
undweak
ist, dassweak
deklariert ist Optional, währendunowned
ist nicht. Durch deklarieren esweak
bekommen Sie den Fall handhaben, dass es vielleicht der null innerhalb der Schließung an einem gewissen Punkt. Wenn Sie versuchen, Zugriff auf eineunowned
variable, die passiert werden null, es stürzt das ganze Programm ab. So verwenden Sie nurunowned
wenn Sie sind positiv, die variable wird immer um während der Schließung ist umInformationsquelleAutor der Antwort drewag
Update 11/2016
Schrieb ich einen Artikel über diese Ausweitung dieser Antwort (in SIL, um zu verstehen, was BOGEN bedeutet), check it out hier.
Ursprüngliche Antwort
Den bisherigen Antworten nicht wirklich geben klare Regeln auf, Wann eine über die andere und warum, so lassen Sie mich hinzufügen, ein paar Dinge.
Den Besitzer oder schwache Diskussion läuft darauf hinaus, eine Frage der Lebensdauer der Variablen und die Schließung verweist.
- Szenarien
Können Sie haben zwei mögliche Szenarien:
Schließung haben die gleiche Lebensdauer der Variablen, so dass die Schließung erreichbar sein wird nur solange, bis die variable erreichbar. Die variable und die Schließung haben die gleiche Lebensdauer. In diesem Fall sollten Sie erklären, die als Referenz Besitzer. Ein gängiges Beispiel ist die
[unowned self]
in vielen Beispiel von kleinen Verschlüssen, die etwas tun, im Rahmen Ihrer Eltern-und das nicht verwiesen wird, überall sonst nicht überleben Ihre Eltern.Verschluss-Lebensdauer ist unabhängig von der variable, der Verschluss könnte noch referenziert werden, wenn die variable nicht mehr erreichbar. In diesem Fall sollten Sie erklären, die als Referenz schwach und stellen Sie sicher, es ist nicht nil ist, bevor Sie ihn verwenden (nicht mit Gewalt packen). Ein typisches Beispiel HIERFÜR ist die
[weak delegate]
können Sie sehen einige Beispiele der Schließung, die auf einen nicht vollständig (lifetime-Weise) delegate-Objekt.Der Tatsächlichen Nutzung
So, das wird/sollte Sie tatsächlich nutzen die meisten der Zeit?
Zitieren Joe Groff aus twitter:
Finden Sie mehr über die Besitzer
*
Innenleben hier.*
In der Regel auch bezeichnet als Besitzer(sicher), um anzuzeigen, dass die Prüfungen zur Laufzeit (, die zu einem Absturz führen nach ungültigen Referenzen) durchgeführt werden, bevor der Zugriff auf den Besitzer verweisen.InformationsquelleAutor der Antwort Umberto Raimondi
Wenn selbst werden könnte-null in der Schließung verwenden [schwache selbst -].
Wenn selbst wird nie null, die in der Schließung verwenden [Besitzer selbst].
Apple Swift-Dokumentation hat einen großen Teil mit Bildern erklärt den Unterschied zwischen der Verwendung starkeschwachund Besitzer in Verschlüsse:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
InformationsquelleAutor der Antwort TenaciousJay
Hier ist brillante Zitate von Apple-Entwickler-Foren beschrieben köstliche details:
unowned
vsunowned(safe)
vsunowned(unsafe)
unowned
vsweak
Update: In der modernen Swift
schwach
intern verwendet den gleichen Mechanismus wieBesitzer
. Also dieser Vergleich ist falsch, da es vergleicht Objective-Cweak
mit Swiftunonwed
.Gründen
Aufgeregt, nicht wahr?
InformationsquelleAutor der Antwort Valentin Shergin
Ich dachte, ich möchte hinzufügen, einige konkrete Beispiele, die speziell für einen view-controller. Viele der Erklärungen, nicht nur hier auf Stack Overflow sind wirklich gut, aber ich arbeite besser mit der realen Welt Beispiele (@drewag hatte einen guten start auf dieser):
weak
weil Sie lange lebte. Der view-controller konnte in der Nähe vordie Anforderung abgeschlossen ist, so
self
nicht mehr Punkte auf ein gültiges Objekt, wenn die Schließung aufgerufen.Wenn Sie Schließung, mit der ein Ereignis auf eine Schaltfläche. Dies kann
unowned
denn sobald der view-controller Weg geht, der button und alle anderen Elemente, es kann sein, Referenzierung vonself
geht Weg, zur gleichen Zeit. Die Schließung der block wird auch verschwinden zur gleichen Zeit.InformationsquelleAutor der Antwort possen
Gibt es einige gute Antworten hier. Aber die jüngsten änderungen wie Swift implementiert schwache Referenzen sollte sich ändern, jeder ist schwach, selbst gegen Besitzer selbst Verwendungsentscheid treffen. Vorher, wenn Sie gebraucht die beste Leistung mit Besitzer selbst überlegen war, zu schwach selbst, solange Sie sicher sein konnten, dass selbst würde nie null, da der Zugriff auf Besitzer selbst ist viel schneller als der Zugriff auf schwachen selbst.
Aber Mike Ash hat dokumentiert, wie Swift aktualisiert hat, die Umsetzung schwach vars zu verwenden, Seite-Tabellen und wie diese verbessert spürbar schwache Leistung selbst.
https://mikeash.com/pyblog/friday-qa-2017-09-22-swift-4-weak-references.html
Nun, dass es nicht eine signifikante Einbußen bei der Leistung zu schwach selbst, ich glaube, wir sollten standardmäßig verwendet, es geht vorwärts. Der Vorteil der selbst schwach ist, dass es optional, die macht es viel einfacher, mehr zu schreiben richtigen code, es ist im Grunde der Grund Swift ist so eine tolle Sprache. Sie mögen denken, Sie wissen, die Situationen sind sicher für die Verwendung von Besitzer selbst, aber meine Erfahrung die Beurteilung von vielen anderen Entwicklern code ist, die meisten nicht. Habe ich behoben, viele crashes, wo die Besitzer selbst wurde aufgehoben, in der Regel in Situationen, in denen ein hintergrund-thread schließt, nachdem ein Domänencontroller freigegeben wird.
Bugs und Abstürze sind die meisten zeitaufwendig, schmerzhaft und teuer Teile der Programmierung. Tun Sie Ihr bestes, richtigen code zu schreiben und Sie zu vermeiden. Ich empfehle, machen Sie es sich zur Regel, nie mit Gewalt packen Sie Optionen, und verwenden Sie niemals Besitzer selbst anstelle des schwachen selbst. Sie nichts verlieren, fehlt den Zeiten Kraft Ausgliedern und Besitzer selbst wirklich sicher sind. Aber Sie gewinnen eine Menge durch den Wegfall schwer zu finden und Debuggen von Abstürzen und bugs.
InformationsquelleAutor der Antwort Randy Hill
Laut Apple-doc
Beispiel -
InformationsquelleAutor der Antwort Jack