Controller-Dealloc wird nicht aufgerufen, wenn NSNotificationCenter-Codeblockmethode mit ARC verwendet wird

8

Wenn ich -addObserverForName: object: queue: usingBlock: für NSNotificationCenter in der Methode -viewDidLoad: meines View-Controllers verwende, wird die Methode -dealloc schließlich nicht aufgerufen.

(Wenn ich -addObserverForName: object: queue: usingBlock: lösche, wird -dealloc erneut aufgerufen.)

Die Verwendung von -addObserver: selector: name: object: scheint dieses Problem nicht zu haben. Was mache ich falsch? (Mein Projekt verwendet ARC.)

Unten ist ein Beispiel für meine Implementierung, falls ich hier etwas falsch mache:

%Vor%

Vielen Dank im Voraus für jede Hilfe.

Ich habe versucht, Folgendes hinzuzufügen (ohne Erfolg):

%Vor%     
James 02.10.2012, 22:09
quelle

3 Antworten

17

updateResult ist eine Instanzvariable, die verhindert, dass das Objekt freigegeben wird, da es von diesem Block beibehalten wird.

Mit anderen Worten, Sie haben einen Retain-Zyklus. Das Objekt behält den Block und der Block behält das Objekt.

Sie müssen einen schwachen oder nicht sicheren Verweis auf diese Instanz und ihre Variable erstellen, um diese Beziehung zu verlieren.

Fügen Sie Folgendes vor Ihrem Benachrichtigungsblock hinzu:

%Vor%

oder (falls Sie auf iOS5 und höher sind)

%Vor%

Dann referenziere innerhalb dieses Blocks das Objekt über die neue schwache Referenz:

%Vor%

Bitte beachten Sie, dass Retain-Zyklen per se keine schlechte Sache sind. Manchmal möchten Sie, dass sie tatsächlich passieren. Aber das sind Fälle, in denen Sie sicher sind, dass der Zyklus nach einer bestimmten Zeit unterbrochen wird (z. B. Animationsblöcke). Der Zyklus wird unterbrochen, sobald der Block ausgeführt wurde und aus dem Stapel entfernt wurde.

    
Till 02.10.2012, 22:26
quelle
6

Dies ist sehr wahrscheinlich, weil Sie einen Retain-Zyklus haben.

Dies ist normalerweise der Fall, wenn Ihr Block implizit self behält und self den Block in gewisser Weise behält. Sie werden einen Retain-Zyklus haben, da jeder den anderen behält, und ihr RetainCount erreicht somit niemals null.

Sie sollten die Warnung -Warc-retain-cycles aktivieren, die Sie vor solchen Problemen warnt.

In Ihrem Fall verwenden Sie also die Variable updateResult , von der ich annahm, dass sie eine Instanzvariable ist, und diese implizit self behält. Sie sollten stattdessen eine temporäre schwache Variable verwenden, um self darzustellen, und diese in Ihrem Block verwenden, so dass sie nicht beibehalten wird und Sie den Retain-Zyklus unterbrechen.

%Vor%     
AliSoftware 02.10.2012 22:29
quelle
0

Dies ist kein Retain-Zyklus.

NSNotificationCenter hält den Block, Block ist self . Weil [NSNotificationCenter defaultCenter] ein Singleton ist, der in jedem App-Lebenszyklus lebt, hält es self indirekt.

    
Jone 19.11.2017 16:21
quelle