2011-10-25 10 views
12

sto ottenendo il seguente errore nel mio app:Core Data: affermazione è ancora attivo

CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. statement is still active with userInfo (null)

Tutto ciò che posso trovare sembra indicare il I può essere avendo problemi multi-threading con l'oggetto dei miei dati di base gestito contesto, ma non riesco a trovare da nessuna parte nella mia app dove questo sarebbe il caso. Sto accedendo e gestendo un contesto dell'oggetto gestito su un thread in background. Il contesto è solo il recupero e la manipolazione di oggetti su quel thread in background. Quando rilevo salvataggi in quel contesto tramite NSManagedObjectContextObjectsDidSaveNotification, sto unendo le modifiche in un contesto diverso che accedo solo al mio thread principale. Quando effettuo la chiamata per unire le modifiche, viene generato l'errore. È molto raro che ciò si verifichi, anche con gli stessi set di dati.

Ho letto da qualche parte che è possibile "abilitare asserzioni multi-thread" utilizzando "-com.apple.CoreData.ThreadingDebug 3", ma non sono riuscito a farlo funzionare. Qualcuno sa se questo è possibile? Speravo che questo potesse attivare alcune asserzioni che mi avrebbero aiutato a trovare dove sto giocando con il contesto sul thread sbagliato o qualcosa del genere.

Eventuali altri indizi su cosa potrebbe accadere o su come rintracciare questo tipo di problema?

+1

la risposta è stata d'aiuto? –

+0

L'hai letto in [TN2124: Mac OS X Debugging Magic] (https://developer.apple.com/library/ios/#technotes/tn2004/tn2124.html#SECCOREDATA). Il bit chiave è, "Questa funzionalità richiede la variante di debug del framework." Se avessi questa variante, potresti impostare la variabile di ambiente 'DYLD_IMAGE_SUFFIX = _debug' e caricherà' CoreData_debug' piuttosto che 'CoreData' per il framework. Sfortunatamente, queste varianti sembrano esistere solo per OS X 10.5.x. :( –

risposta

13

Ho avuto un problema simile e ho trovato un modo per risolverlo.

Ho creato un meccanismo per creare diversi contesti basati su nomi di thread (1 thread = 1 contesto).

#include <pthread.h> 
... 

    mach_port_t threadID = pthread_mach_thread_np(pthread_self()); 
    NSString *threadName = [NSString stringWithFormat:@"%x", threadID]; 
    NSManagedObjectContext *context = [singleton.threadsContexts objectForKey:threadName]; 
    if (!context) { 
     NSLog(@"Creating managed context for thread named '%@'", threadName); 
     context = [[NSManagedObjectContext alloc] init]; 
     [context setPersistentStoreCoordinator:[singleton.managedObjectContext persistentStoreCoordinator]]; 

     //initialize dictionary in your singleton if it as not been yet 
     if(!singleton.threadsContexts) 
     { 
      singleton.threadsContexts = [NSMutableDictionary new]; 
     } 
     [singleton.threadsContexts setObject:context forKey:threadName]; 
    } 

    return result; 

e poi, quando ho bisogno di una versione completa di un oggetto gestito in un thread in background, ottengo una copia dell'oggetto dedicato a questa discussione:

NSManagedObjectModel *myNewObject = [myBackgroundContext objectWithID:[myObject objectID]]; 

Speranza questa risposta sarà di aiuto.

+1

[[NSThread currentThread] nome] restituisce "" per me su iOS 7. [Questa risposta] (http://stackoverflow.com/a/15523049/1571490) mi ha fornito una stringa corretta. Oltre a ciò, ha funzionato perfettamente e sembra che tutti i miei problemi di threading di Core Data siano risolti Grazie! – fifarunnerr

+0

Funziona alla grande! Non ho visto il mio crash da quando uso questo codice! Ho anche dovuto usare la tecnica di fifa per ottenere il nome del thread. t dimenticare di inizializzare NSMutableDictionary nel tuo singleton ... Ho girato un po 'in cerchio fino a quando ho capito che: DUH :: – RyanG

+1

Questa è una risposta piuttosto vecchia e per i progetti più recenti, sto usando la Magical Record che ha una -in supporto per i dati principali multi-threading.La documentazione non è eccezionale ma consente di risparmiare un sacco di tempo una volta che sai come usare questa libreria https://github.com/magicalpanda/MagicalRecord –