Objective C Blockiert als Async-Callbacks und BAD ACCESS

9

Ich habe ernsthafte Zweifel. Angenommen, das folgende Szenario:

  1. Sie haben UIViewController auf dem Bildschirm.
  2. Die App initiiert beispielsweise einen Back-End-Anruf mit einem Block als Rückruf
  3. Sie verwenden ein "Selbst" -Surrogate, um Retain-Zyklen zu verhindern.
  4. Der Benutzer trifft auf "Zurück" und die UIViewController wird freigegeben.
  5. Früher oder später wird der Rückrufblock ausgeführt & gt; & gt; %Code%

Vor iOS 4 haben wir uns mit dieser Art von Situation beschäftigt, indem wir auf BAD ACCESS die nil -Eigenschaft von ... gesetzt haben. Ich weiß nicht, welche Klasse Sie auch verwenden.

Aber heutzutage ... wie stornierst du einen Block ??. Was ist, wenn der Block an eine statische Methode gesendet wurde und Sie keine Möglichkeit haben, diese Rückrufreferenz zu löschen?.

In diesem Fall sollten wir vermeiden, den "Selbst" -Surrogat zu verwenden?

Übrigens, mit "Selbstersatz" möchte ich sagen:

%Vor%

Danke !!

    
Jorge Leandro Perez 30.07.2011, 19:27
quelle

2 Antworten

5

Nun, zuerst einmal: Wenn (und nur wenn) Ihr Grund dafür, die Verwendung von self oder den direkten Zugriff von Ivars innerhalb eines Blocks zu vermeiden, wirklich Retain-Zyklen sind, sollten Sie sich in einer Situation wie

befinden %Vor%

(wobei => bedeutet "hat einen starken Bezug auf").

In diesem Fall sollte blockWithWeakBackReference immer nur von objectA aufgerufen werden, daher besteht keine Gefahr eines SCHLECHTEN ZUGRIFFS.

Wenn ich Ihre Frage richtig verstanden habe, meinen Sie ein anderes Szenario:

  • objectA möchte, dass ein anwendungsweiter Dienst einen Block in seinem Namen ausführt , wenn eine Vorbedingung erfüllt ist.
  • Sie vermeiden die Verwendung von self innerhalb des Blocks, da Sie objectA vor der Ausführung des Blocks ablegen möchten.

Ein Beispiel hierfür könnte eine gemeinsam genutzte Netzwerkwarteschlange sein, die einen Block ausführt, wenn die Anforderung aus irgendeinem Grund beendet wurde.

In diesem Fall würde ich vorschlagen, einfach das Design von NSNotificationCenter 's addObserverForName:object:queue:usingBlock: zu kopieren und Ihren Service dazu zu bringen, ein paar Methoden wie -(SomeTokenObjectType)addWorkerBlock:(void(^)(whatever-signature-makes-sense-for-you)) und -(void)cancelWorkerBlockWithToken:(SomeTokenObjectType) zu implementieren, um Ihre Callback- Blöcke.

Dann können alle Objekte, die diesen Service verwenden, einfach einen ivar vom Typ NSMutableSet haben, um das Token für jeden in die Warteschlange eingereihten Block zu speichern und - in ihrer dealloc - die verbleibenden Tokens aufzulisten und sie mit dem Service zu löschen. p>     

danyowdee 01.08.2011, 16:39
quelle
0

"um Retain-Zyklen zu verhindern."

Aber haben Sie wirklich einen Retain-Zyklus zu verhindern? Denk darüber nach. Der Block behält self (Ihr View-Controller). Der Back-End-Aufruf behält den Block bei. Aber wo behält self den Block?

    
newacct 23.10.2012 18:52
quelle