Questa riga di codice viene chiamata nel mio metodo awakeFromFetch
situato all'interno di un oggetto gestito personalizzato che implementa NSManagedObject
. Questa linea, in particolare, sta effettuando una chiamata alla mia classe di gestore di rete singleton denominata sharedManager
.Dispatch una volta (dispatch_once) singleton si blocca/blocca nell'obiettivo c
[self setSync:(![[WKNetworkManager sharedManager] objectHasPendingRequests:self.objectID]) ];
Il blocco dispatch_once verrà colpito come mostrato di seguito. Si noti che è implementato in senso buono, come è mostrato here:
La chiamata dispatch_once poi va a once.h e qui si blocca proprio sulla linea evidenziata:
Ecco la traccia dello stack:
Tutto questo accade quando si tenta di caricare un file di coda di rete precedentemente salvato. L'applicazione viene chiusa completamente per salvare, quindi viene avviata nuovamente e quindi si verifica questo blocco/blocco.
Ho anche provato a utilizzare questo codice per risolvere il problema come suggerito here e non ha funzionato. Ma cambiare questo probabilmente non importa in ogni caso, come il mio codice dispatch_once originale ha funzionato bene per molto tempo. È solo in questo caso particolare.
if ([NSThread isMainThread])
{
dispatch_once(&onceToken, ^{
stack = [[KACoreDataStack alloc] init];});
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
dispatch_once(&onceToken, ^{
stack = [[KACoreDataStack alloc] init];});
});
}
Finora, queste sono le mie fonti per la risoluzione di questo tipo di problema:
- Code execution stops on using thread safe Singleton initialization code
- http://cocoasamurai.blogspot.jp/2011/04/singletons-your-doing-them-wrong.html
- http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial
- ios singleton class crashes my app
- http://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
- http://www.bignerdranch.com/blog/dispatch_once-upon-a-time/
Grazie per il vostro aiuto!
Grazie! Penso che tu sia certamente interessato all'architettura. L'intero caricamento da disco è stato aggiunto dopo che l'app è stata progettata e ovviamente non sta giocando bene con esso. WKNetworkManager (sharedManager) chiama '[self loadQueueFromDisk];'. Quindi, a sua volta, creando gli oggetti decodificati, tali inizializzazioni dell'oggetto attivano le chiamate a sharedManager. Questo potrebbe certamente essere problematico. La soluzione collegata sembra ingombrante. Pensi che fare una dichiarazione di blocco di loadQueueFromDisk per delegare l'attività a un altro thread funzionerebbe? – Marcel
Se ti piace la domanda, invitala! – Raspu
Bene, Core Data e threading, che possono complicarsi rapidamente. La mia prima inclinazione all'inizializzazione del Core Data di questo tipo è di lanciarla nella coda GCD a bassa priorità 'dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_LOW, 0),^{[self loadQueueFromDisk];});' quindi viene preso in considerazione una volta le code di priorità alta e normale sono vuote. Poiché è probabile che sia il comportamento desiderato durante l'avvio. –