2009-08-12 9 views
6

Estoy desarrollando una aplicación en cacao. Estoy enfrentando un problema crítico."Datos principales no pudieron cumplir un error ..." error

estoy eliminando las entradas de un objeto denominado "Directorio" en la base de datos utilizando el siguiente código:

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

Pero a veces una excepción como "datos básicos no podía cumplir un fallo .." se produce al intentar guardar después de la eliminación. Estoy usando el código [managedObjectContext save];

Soy nuevo en Core Data ... Estoy deseando encontrar una solución.

+1

Mire el tercer párrafo aquí: [La falla no se puede cumplir] (http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdTroubleshooting.html#//apple_ref/doc/uid/TP40002320- SW7) –

+0

¿Pero cómo depurar y descubrir cuál es el módulo exacto que causa esta excepción? –

Respuesta

4

Esta es una vieja pregunta, he tenido problemas resolviendo esto desde hace un tiempo. Entonces, pensé que sería mejor documentarlo.

Como Weichsel mencionado anteriormente, the Apple documentation indica acertadamente el motivo de esta excepción. Pero es un trabajo agitado identificar el módulo debido a que se conserva el objeto de la subclase NSManagedObject (si el motivo primero citado en la documentación es la causa raíz del problema).

Por lo tanto, comencé identificando las partes de mi código que conservaba NSManagedObject, en su lugar retenía NSManagedObjectID y creaba el objeto administrado cuando era necesario. La discusión en líneas similares se pueden encontrar en la documentación Restkit:

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

actualizado mi setter y getter para que la interfaz con el resto de los módulos permanecen iguales mientras internamente que ahora dependemos sobre NSManagedObjectID y evitar la retención de 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]]; 
    } 
} 

la anterior es la primera hal f del problema resuelto. Necesitamos descubrir la dependencia en partes sospechosas de nuestra aplicación y eliminarla.

Hubo otro problema también, instruments -> allocations es una buena fuente para averiguar qué módulos retienen realmente los objetos gestionados, el objeto de excepción tendría detalles sobre qué objeto gestionado está creando el problema, filtra los resultados para ese objeto que se muestra a continuación:

Instruments - Allocations

estábamos realizando MVA en un objeto gestionado. KVO retiene el objeto gestionado observado y, por lo tanto, se lanza la excepción y su seguimiento no sería desde nuestro proyecto. Estos son muy difíciles de depurar, pero adivinar el trabajo y el seguimiento de la asignación del objeto y el ciclo de retención y liberación seguramente ayudarán. Eliminé la parte de observación de KVO y todo comenzó a funcionar.

+0

+1 para el enlace de Apple Doc – Martin

Cuestiones relacionadas