Swift hat:
- Starke Referenzen
- Schwache Referenzen
- Nicht besessene Referenzen
Wie unterscheidet sich eine nicht besessene Referenz von einer schwachen Referenz?
Wann ist es sicher, eine nicht im Besitz befindliche Referenz zu verwenden?
Sind nicht besessene Referenzen ein Sicherheitsrisiko wie baumelnde Zeiger in C / C ++?
unowned
für die Klassen, die wir steuern, für Apple-Klassen zu verwenden,weak
weil wir nicht sicher garantieren können, was es tutAntworten:
Sowohl
weak
als auchunowned
Referenzen erzeugen keinenstrong
Halt für das referenzierte Objekt (auch bekannt als Erhöhung der Aufbewahrungsanzahl, um zu verhindern, dass ARC die Zuordnung des referenzierten Objekts aufhebt).Aber warum zwei Schlüsselwörter? Diese Unterscheidung hat damit zu tun, dass
Optional
Typen in der Swift-Sprache integriert sind. Lange Rede, kurzer Sinn: Optionale Typen bieten Speichersicherheit (dies funktioniert hervorragend mit den Konstruktorregeln von Swift, die streng sind, um diesen Vorteil zu bieten).Eine
weak
Referenz ermöglicht die Möglichkeit, dass sie wirdnil
(dies geschieht automatisch, wenn die Zuordnung des referenzierten Objekts aufgehoben wird). Daher muss der Typ Ihrer Eigenschaft optional sein. Sie als Programmierer sind daher verpflichtet, diese zu überprüfen, bevor Sie sie verwenden (im Grunde genommen die Der Compiler zwingt Sie so weit wie möglich, sicheren Code zu schreiben.Eine
unowned
Referenz geht davon aus, dass es zunil
Lebzeiten niemals werden wird . Während der Initialisierung muss eine nicht besessene Referenz festgelegt werden. Dies bedeutet, dass die Referenz als nicht optionaler Typ definiert wird, der ohne Überprüfungen sicher verwendet werden kann. Wenn die Zuordnung des Objekts, auf das verwiesen wird, irgendwie aufgehoben wird, stürzt die App ab, wenn die nicht besessene Referenz verwendet wird.Aus den Apple-Dokumenten :
In den Dokumenten finden Sie einige Beispiele, in denen die Aufbewahrungszyklen und deren Unterbrechung erläutert werden. Alle diese Beispiele werden aus den Dokumenten extrahiert .
Beispiel für das
weak
Schlüsselwort:Und jetzt zu einigen ASCII-Grafiken (Sie sollten sich die Dokumente ansehen - sie haben hübsche Diagramme):
Das Beispiel
Person
undApartment
zeigt eine Situation, in der zwei Eigenschaften, die beide gleich Null sein dürfen, möglicherweise einen starken Referenzzyklus verursachen. Dieses Szenario lässt sich am besten mit einer schwachen Referenz lösen. Beide Entitäten können existieren, ohne eine strikte Abhängigkeit voneinander zu haben.Beispiel für das
unowned
Schlüsselwort:In diesem Beispiel kann a ein
Customer
haben oder nichtCreditCard
, aber aCreditCard
wird immer mit a verknüpftCustomer
. Um dies darzustellen, verfügt dieCustomer
Klasse über eine optionalecard
Eigenschaft, dieCreditCard
Klasse jedoch über eine nicht optionale (und nicht besessene)customer
Eigenschaft.Das Beispiel
Customer
undCreditCard
zeigt eine Situation, in der eine Eigenschaft, die Null sein darf, und eine andere Eigenschaft, die nicht Null sein darf, möglicherweise einen starken Referenzzyklus verursachen. Dieses Szenario lässt sich am besten mit einer nicht besessenen Referenz lösen.Anmerkung von Apple:
Es gibt auch ein drittes Szenario, in dem beide Eigenschaften immer einen Wert haben sollten und keine Eigenschaft nach Abschluss der Initialisierung jemals Null sein sollte.
Außerdem gibt es die klassischen Szenarien für den Beibehaltungszyklus, die beim Arbeiten mit Verschlüssen vermieden werden sollten.
Zu diesem Zweck empfehle ich Ihnen, die Apple-Dokumente zu besuchen oder das Buch zu lesen .
quelle
weak var Person?
vs.var Person?
?Q1. Wie unterscheidet sich eine "nicht genannte Referenz" von einer "schwachen Referenz"?
Schwache Referenz:
Unbesessene Referenz:
Wann verwenden Sie jedes:
Q2. Wann ist es sicher, eine „nicht im Besitz befindliche Referenz“ zu verwenden?
Wie oben zitiert, wird angenommen, dass eine nicht besessene Referenz immer einen Wert hat. Sie sollten es also nur verwenden, wenn Sie sicher sind, dass die Referenz niemals Null sein wird. Apple Docs veranschaulichen anhand des folgenden Beispiels einen Anwendungsfall für nicht besessene Referenzen.
Angenommen, wir haben zwei Klassen
Customer
undCreditCard
. Ein Kunde kann ohne Kreditkarte existieren, aber eine Kreditkarte wird nicht ohne Kunden existieren, dh es kann angenommen werden, dass eine Kreditkarte immer einen Kunden hat. Sie sollten also die folgende Beziehung haben:Q3. Sind "nicht besessene Referenzen" ein Sicherheitsrisiko wie "baumelnde Zeiger" in C / C ++?
Das glaube ich nicht.
Da nicht besessene Referenzen nur schwache Referenzen sind, deren Wert garantiert ist, sollte dies in keiner Weise ein Sicherheitsrisiko darstellen. Wenn Sie jedoch versuchen, auf eine nicht besessene Referenz zuzugreifen, nachdem die Zuweisung der Instanz, auf die sie verweist, freigegeben wurde, wird ein Laufzeitfehler ausgelöst und die App stürzt ab.
Das ist das einzige Risiko, das ich damit sehe.
Link zu Apple Docs
quelle
unowned
für die Eigenschaft parent in der untergeordneten Klasse. schwach ist umgekehrt. Schöne Erklärung @myxtic!unowned
Referenzen sind nurweak
Referenzen, die garantiert einen Wert haben!Wenn das Selbst im Verschluss gleich Null sein könnte, benutze [schwaches Selbst] .
Wenn das Selbst im Verschluss niemals Null sein wird, benutze [nicht besessenes Selbst] .
Wenn es abstürzt, wenn Sie [nicht besessenes Selbst] verwenden, ist Selbst wahrscheinlich irgendwann in diesem Abschluss gleich Null und Sie müssen wahrscheinlich stattdessen [schwaches Selbst] verwenden.
Schauen Sie sich die Beispiele zur Verwendung von starken , schwachen und nicht besessenen Verschlüssen an:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
quelle
self
Null sein, wenn ich in viewDidLoad () einen Abschluss verwende ?Auszüge aus dem Link
Einige abschließende Punkte
quelle
Beides
weak
undunowned
Referenzen wirken sich nicht auf die Referenzanzahl des Objekts aus. Eine schwache Referenz ist jedoch immer optional, dh sie kann gleich Null seinunowned
Referenzen niemals null sein können, sodass sie niemals optional sind. Wenn Sie eine optionale Referenz verwenden, müssen Sie immer die Möglichkeit berücksichtigen, dass das Objekt Null ist. Im Falle einer nicht besessenen Referenz müssen Sie sicherstellen, dass das Objekt niemals Null ist. Die Verwendung eines nicht besessenen Verweises auf ein Null-Objekt ähnelt dem gewaltsamen Auspacken einer Option, die Null ist.Es ist jedoch sicher, eine nicht im Besitz befindliche Referenz zu verwenden, bei der Sie sicher sind, dass die Lebensdauer des Objekts länger ist als die der Referenz. Ist dies nicht der Fall, ist es besser, stattdessen eine schwache Referenz zu verwenden.
Was den dritten Teil der Frage betrifft, denke ich nicht, dass eine nicht besessene Referenz einem baumelnden Zeiger ähnelt. Wenn wir über die Referenzanzahl sprechen, beziehen wir uns normalerweise auf die starke Referenzanzahl des Objekts. In ähnlicher Weise behält Swift die Anzahl der nicht besessenen Referenzen und die Anzahl der schwachen Referenzen für das Objekt bei (schwache Referenzpunkte verweisen eher auf eine sogenannte "Beistelltabelle" als auf das Objekt selbst). Wenn der starke Referenzzähler Null erreicht, wird das Objekt deinitialisiert, kann jedoch nicht freigegeben werden, wenn der nicht besessene Referenzzähler größer als Null ist.
Jetzt ist ein baumelnder Zeiger etwas, das auf einen Speicherplatz verweist, der bereits freigegeben wurde. Da der Speicher jedoch nur dann freigegeben werden kann, wenn ein nicht besessener Verweis auf das Objekt vorhanden ist, kann er keinen baumelnden Zeiger verursachen.
Es gibt viele Artikel, in denen die schnelle Speicherverwaltung ausführlicher behandelt wird. Hier ist einer.
quelle
Nicht besessene Referenzen sind eine Art schwache Referenz, die im Fall einer Beziehung mit gleicher Lebensdauer zwischen zwei Objekten verwendet wird, wenn ein Objekt immer nur einem anderen Objekt gehören sollte. Auf diese Weise können Sie eine unveränderliche Bindung zwischen einem Objekt und einer seiner Eigenschaften herstellen.
In dem Beispiel im schnellen WWDC-Zwischenvideo besitzt eine Person eine Kreditkarte, und eine Kreditkarte kann nur einen Inhaber haben. Auf der Kreditkarte sollte die Person keine optionale Eigenschaft sein, da Sie nicht möchten, dass eine Kreditkarte mit nur einem Eigentümer herumschwirrt. Sie können diesen Zyklus durchbrechen, indem Sie die Inhaber-Eigenschaft des Kredits zu einer schwachen Referenz machen. Dazu müssen Sie sie jedoch sowohl optional als auch variabel (im Gegensatz zur Konstanten) machen. Die nicht besessene Referenz in diesem Fall bedeutet, dass CreditCard zwar keine Beteiligung an einer Person besitzt, deren Leben jedoch davon abhängt.
quelle
Verwenden
unowned
Sie diese Option, wenn Sie sicher sind, dass Sieself
niemalsnil
an dem Punkt sein können, auf den Sie zugreifenself
an diesem Punkt .Beispiel (Sie können das Ziel natürlich direkt von hinzufügen
MyViewController
, aber es ist wieder ein einfaches Beispiel):Verwenden Sie diese Option, wenn an dem Punkt, auf den Sie zugreifen,
weak
eine Möglichkeit bestehtself
nil
self
.Beispiel:
Nachteile von
unowned
:Nachteile von
weak
:Wenn Sie sich nicht sicher sind, verwenden Sie
weak
. Warten Sie , ich meine, fragen Sie hier auf StackOverflow, was Sie in Ihrem Fall tun sollten! Die ständige Verwendung von Schwachstellen, wenn Sie dies nicht tun sollten, ist für Sie und den Leser Ihres Codes nur verwirrend.quelle