einmal versenden (dispatch_once) Singleton friert / sperrt in Ziel c

8

Diese Codezeile wird in meiner awakeFromFetch -Methode aufgerufen, die sich in einem benutzerdefinierten verwalteten Objekt befindet, das NSManagedObject implementiert. Diese Zeile ruft insbesondere meine Singleton Network Manager-Klasse namens sharedManager auf.

%Vor%

Der dispatch_once Block wird wie unten gezeigt getroffen. Beachten Sie, dass es auf eine gute Art implementiert ist, wie gezeigt hier :

Der Aufruf dispatch_once geht dann zu once.h und hier friert er direkt in der markierten Zeile ein:

Hier ist der Stack-Trace:

All dies geschieht, wenn Sie versuchen, eine zuvor gespeicherte Netzwerkwarteschlangendatei zu laden. Die Anwendung wird vollständig geschlossen, um zu speichern und dann erneut gestartet, und dann erfolgt das Einfrieren / Sperren.

Ich habe sogar versucht, diesen Code stattdessen zu verwenden, um das Problem zu lösen, wie es vorgeschlagen wird. hier , und es hat nicht funktioniert. Aber es wäre wahrscheinlich egal, dies zu ändern, da mein ursprünglicher dispatch_once-Code lange gut funktioniert hat. Es ist nur in diesem speziellen Fall.

%Vor%

Bisher sind dies meine Quellen, um diese Art von Problem zu beheben:

Danke für Ihre Hilfe!

    
Marcel 18.02.2015, 23:58
quelle

2 Antworten

0

Dank der Hilfe von alexcurylo wurde der Job loadFromDisk in die Warteschlange gestellt. Damit die Leute nicht verwirrt sind, stehe ich mit dem folgenden Code in der Warteschlange eines Jobs, der ein Array (das als eine gespeicherte Warteschlange von Benutzeranforderungen fungiert) von der Festplatte lädt. Sie könnten einen Job in die Warteschlange stellen, z. B. das Laden von Bildern usw. Der folgende Code in meiner sharedManager-Klasse (in dem die Ladung von der Festplatte aufgerufen wird) funktionierte, wie hier gezeigt:

%Vor%     
Marcel 19.02.2015, 18:39
quelle
6

Verdammter Sohn, das ist eine gute Aufgabe, Fragen zu stellen.

Das Problem hierbei ist, dass rekursive Aufrufe von dispatch_once Deadlocks sind. Wenn Sie genaue Details wünschen, können Sie sie mit der Quelle hier finden . Sie müssen also neu schreiben, um das zu vermeiden.

Ich bin der Meinung, dass es einen architektonischen Fehltritt gibt, der zu diesem -loadQueueFromDisk -Aufruf führt. Sie tun absolut nicht , etwas zu tun, was in der Ausführungszeit möglicherweise unbegrenzt ist, als wenn Sie etwas von der Festplatte in einem dispatch_once laden. Was Sie tun möchten, ist das absolute Minimum, um ein adressierbares Singleton zu erstellen und wieder herauszukommen. Geben Sie dann einen internen Status von "Initializing" ein, und senden Sie das Disk-Loading-Zeug irgendwo in eine nicht blockierende Warteschlange. Auf diese Weise kann alles, was nicht von dem von der Festplatte geladenen Material abhängt, fortgesetzt werden, und alles, was von dem von der Platte geladenen Material abhängt, kann sich der Warteschlange hinzufügen oder alle paar hundert Millisekunden nachsehen wenn es sich noch in einem "initialisierten" Zustand befindet oder etwas in dieser Richtung.

    
Alex Curylo 19.02.2015 02:59
quelle