2009-08-12 2 views
6

Sto sviluppando un'applicazione nel cacao. Sto affrontando un problema critico."I dati principali non hanno potuto soddisfare un errore .." errore

Sto eliminando le voci di un oggetto denominato "Directory" in Core Data utilizzando il seguente codice:

NSEnumerator *tempDirectories = [[folderArrayController arrangedObjects] objectEnumerator]; 
id tempDirectory; 
while (tempDirectory = [tempDirectories nextObject]){ 
    [managedObjectContext deleteObject:tempDirectory]; 
} 

Ma a volte un'eccezione come "Core Data non poteva compiere un errore .." si verifica durante il tentativo di salva dopo la cancellazione. Sto usando il codice [managedObjectContext save];

Sono nuovo in Core Data ... In attesa di una soluzione.

+1

Guarda il terzo paragrafo qui: [Errore non può essere soddisfatto] (http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdTroubleshooting.html#//apple_ref/doc/uid/TP40002320- SW7) –

+0

Ma come eseguire il debug e scoprire quale è il modulo esatto che causa questa eccezione? –

risposta

4

Questa è una vecchia domanda, ho faticato a risolverlo da un po 'di tempo. Quindi, ho pensato che sarebbe stato meglio documentarlo.

As Weichsel sopra menzionato, the Apple documentation giustamente sottolinea ragione di questa eccezione. Ma è un lavoro frenetico identificare il modulo a causa del quale l'oggetto della sottoclasse NSManagedObject viene conservato (se il motivo citato nella documentazione è la causa principale del problema).

Quindi, ho iniziato identificando le parti del mio codice che mantenevano NSManagedObject, invece ho mantenuto NSManagedObjectID e ne ho creato l'oggetto gestito quando necessario. La discussione in linee simili si possono trovare nella documentazione Restkit:

  1. https://github.com/RestKit/RestKit/commit/170060549f44ee5a822ac3e93668dad3b396dc39
  2. https://github.com/RestKit/RestKit/issues/611#issuecomment-4858605

aggiornato il mio setter e getter modo che l'interfaccia con il riposo dei moduli rimangono stessa, mentre internamente che ora dipendiamo upon NSManagedObjectID ed evitare ritegno di NSManageObject:

-(CSTaskAbstract*)task 
{ 
    CSTaskAbstract *theTask = nil; 
    if (self.taskObjectID) 
    { 
     NSManagedObjectContext *moc = [(CSAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
     // https://github.com/RestKit/RestKit/commit/170060549f44ee5a822ac3e93668dad3b396dc39 & 
     // https://github.com/RestKit/RestKit/issues/611#issuecomment-4858605 
     NSError *theError = nil; 
     NSManagedObject *theObject = [moc existingObjectWithID:self.taskObjectID 
                 error:&theError]; 
     if ([theObject isKindOfClass:[CSTaskAbstract class]]) 
     { 
      theTask = (CSTaskAbstract*)theObject; 
     } 
    } 
    return theTask; 
} 
-(void)setTask:(CSTaskAbstract *)inTask 
{ 
    if (inTask!=self.task) 
    { 
     // Consequences of retaining a MO when it is detached from its MOC 
     [self setTaskObjectID:[inTask objectID]]; 
    } 
} 

Quanto sopra è il primo hal f del problema risolto. Dobbiamo scoprire la dipendenza da parti sospette della nostra app ed eliminarla.

C'era qualche altro problema, strumenti -> allocazioni è una buona fonte per scoprire quali moduli stanno effettivamente conservando gli oggetti gestiti, l'oggetto eccezione avrebbe dettagli su quale oggetto gestito sta creando il problema, filtrare i risultati per quello oggetto come illustrato di seguito:

Instruments - Allocations

suonavamo KVO su un oggetto gestito. KVO conserva l'oggetto gestito osservato e quindi l'eccezione viene generata e la traccia di ritorno non proviene dal nostro progetto. È molto difficile eseguire il debug, ma è probabile che il lavoro e il tracciamento dell'allocazione degli oggetti e il ciclo di conservazione del rilascio siano sicuramente d'aiuto. Ho rimosso la parte di osservazione KVO e tutto ha iniziato a funzionare.

+0

+1 per il collegamento Apple doc – Martin