Lazy Initialisierung und behalten Zyklus

8

Gibt es bei Verwendung von Lazy-Initialisierern die Möglichkeit, Retain-Zyklen zu haben?

In einem Blogpost und vielen anderen Orten wird [unowned self] gesehen

%Vor%

Ich habe das versucht

%Vor%

Benutzte es so

%Vor%

Und festgestellt, dass "person deinit" wurde protokolliert.

So scheint es, dass es keine Retain-Zyklen gibt. Nach meinem Wissen, wenn ein Block Selbst erfasst und wenn dieser Block stark von Selbst zurückgehalten wird, gibt es einen Retain-Zyklus. Dieser Fall scheint einem Retain-Zyklus ähnlich zu sein, ist es aber nicht.

    
BangOperator 01.07.2016, 09:02
quelle

2 Antworten

25
  

Ich habe das versucht [...]

%Vor%
  

es scheint, dass es keine Retain-Zyklen gibt

Korrigieren.

Der Grund dafür ist, dass der sofort angewendete Abschluss {}() als @noescape gilt. Das erfasste self wird nicht beibehalten.

Als Referenz: Joe Groffs Tweet .

    
Nikolai Ruhe 01.07.2016, 11:22
quelle
2

In diesem Fall benötigen Sie keine Erfassungsliste, da nach der Instanziierung von self kein Verweis personalizedGreeting vorhanden ist.

Wie MartinR in seinem Kommentar schreibt, können Sie Ihre Hypothese leicht testen, indem Sie protokollieren, ob ein Objekt Person deinitilt oder nicht, wenn Sie die Aufnahmeliste entfernen.

z. B.

%Vor%

Es ist offensichtlich, dass in diesem Fall kein Risiko für einen starken Referenzzyklus besteht und daher die Erfassungsliste von unowned self im Lazy Closure nicht benötigt wird. Der Grund hierfür ist, dass die verzögerte Schließung nur einmal ausführt und nur den Rückgabewert des Abschlusses verwendet, um personalizedGreeting (träge) zu instanziieren, während der Verweis auf self nicht, in In diesem Fall überleben die Ausführung der Schließung.

Wenn wir eine ähnliche Schließung in einer Klasseneigenschaft von Person speichern würden, würden wir jedoch einen starken Referenzzyklus erstellen, da eine Eigenschaft von self eine starke Referenz zurück zu self hätte. Zum Beispiel:

%Vor%

Hypothese: Faule Instanziierung von Schließungen erfasst automatisch self als weak (oder unowned ), standardmäßig

Wenn wir das folgende Beispiel betrachten, erkennen wir, dass diese Hypothese falsch ist.

%Vor%

I.e., f in foo() wird nicht entmineralisiert, und angesichts dieses starken Referenzzyklus können wir die Schlussfolgerung ziehen, dass self beim instanziierenden Schließen der Lazy-Variablen dummy stark erfasst wird.

Wir können auch sehen, dass wir nie den starken Referenzzyklus erzeugen, falls wir niemals dummy instanziieren, was unterstützen würde, dass die fast einmalige faule instantiierende Schließung als Laufzeitbereich betrachtet werden kann (ähnlich wie nie erreicht, wenn) das ist entweder a) nie erreicht (nicht initialisiert) oder b) erreicht, vollständig ausgeführt und "weggeworfen" (Ende des Geltungsbereichs).

%Vor%

Weitere Informationen zu starken Referenzzyklen finden Sie z. B. in

dfri 01.07.2016 09:14
quelle

Tags und Links