Los datos básicos no persisten en las actualizaciones de properties de la database

Estoy trabajando con una subclass de NSManagedObject. En realidad, henetworkinga de una class que henetworkinga de una class que se henetworkinga de NSManagedObject (que no debería ser un problema, ¿verdad?).

El problema

Después de realizar cambios en las properties del object, el object restring los cambios durante su vida útil, pero los cambios nunca se guardan en la database.

¿Cómo sé esto?

Lo sé porque:

  • cuando reinicio la aplicación, los cambios que he realizado se pierden.
  • diciéndole al context que actualice el object – DESPUÉS de haber realizado cambios en el object y le dije al context que guarde – establece los valores del object en su estado original antes de realizar los cambios.
  • cuando ejecuto la aplicación en el simulador, puedo mirar el file de database sqlite en el Finder, y su date de modificación no se actualiza cuando bash save el context.

¡No se está escribiendo nada en la database!

Context

Estoy usando los methods de delegado generados automáticamente para crear el coordinador de la tienda y el context. Luego, paso el context a los controlleres de vista en sus methods init, como se recomienda en los documentos. La tienda es SQLite.

Puedo insert objects con éxito en la database y leerlos. Incluso puedo hacer cambios de propiedad en el object recién insertado y savelo con éxito. Simplemente no parece poder actualizar las properties del object cuando el object se retira de la database.

El object se obtiene de la tienda a través de una relación de otro object. Después de hacer cambios a sus properties, llamo al método de save del context. Sin embargo, antes de hacerlo, invoco el método isUpdated del object y el método hasChanges del context, y ambos devuelven false. ¿No deberían volver verdad, ya que acabo de hacer cambios en las properties del object pero no he guardado el context?

Más

Si llamo al método commitChanges del object antes de save el context, sin embargo, al pasar los nombres de las properties que he cambiado, obtengo los valores correctos de las properties. No estoy seguro de lo que esto significa. Hubiera pensado que esto significa que los nuevos valores de propiedad del object se han guardado con éxito, pero claramente no se guardan.

Sé que los objects resultantes están registrados con un context. Si llamo

[[result managedObjectContext] refreshObject:result mergeChanges:YES]; 

el object vuelve a los valores de propiedad originales. Esto significa que el context está ahí y que es el mismo context desde el que se obtuvo el logging. Y significa que los nuevos valores de propiedad nunca se escriben en la database.

Algún Código

Aquí está el código en el que estoy hurgando con todas estas cosas. Hay otros lugares en mi código donde estoy haciendo cambios de properties, pero los cambios nunca se guardan.

 - (IBAction)statusControlChanged:(UISegmentedControl *)control { WCAAssessmentResult *result = [self currentResult]; /* printing the existing property values */ if (![result.complete boolValue]) NSLog(@"result is in progress!"); else if ([result.passed boolValue]) NSLog(@"result is passed!"); else NSLog(@"result is not passed!"); /* changing the property values */ switch (control.selectedSegmentIndex) { case 0: NSLog(@"setting incomplete"); result.complete = [NSNumber numberWithBool:NO]; break; case 1: NSLog(@"setting passed"); result.passed = [NSNumber numberWithBool:YES]; result.complete = [NSNumber numberWithBool:YES]; break; case 2: NSLog(@"setting failed"); result.passed = [NSNumber numberWithBool:NO]; result.complete = [NSNumber numberWithBool:YES]; break; default: break; } /* this method always returns an empty dictionary */ NSLog(@"%@", [result changedValues]); /* this method returns the values that I just set */ NSLog(@"%@", [result committedValuesForKeys:[NSArray arrayWithObjects:@"complete", @"passed", nil]]); /* isUpdated returns false */ if (![result isUpdated]) { NSLog(@"result is not updated?! WTF!?!?"); } /* hasChanges returns false */ if (![[result managedObjectContext] hasChanges]) { NSLog(@"context has no changes!? WTF!?!?"); } /* saving the context produces no error */ NSError *error = nil; if (![[result managedObjectContext] save:&error]) { NSLog(@"save failed"); NSLog(@"%@",[error description]); } } 

Un giro

Si creo un nuevo object de resultados insertando un nuevo logging en el context, puedo establecer las properties de ese object y se guardan correctamente. En el código anterior, estoy buscando el object como miembro de una asociación de muchos otros objects. ¿Esa es una pista?

Estoy desgarrando mi cabello por esto. ¿Qué demonios podría estar mal aquí?

¿Qué NO es el problema?

  • He registrado la class del object, y de hecho es la class correcta
  • Me he asegurado de que managedObjectContext que estoy guardando es el mismo que el context del object
  • No he realizado ningún cambio en los methods setter / getter generados automáticamente de mis classs de object administrado
  • He intentado usar el método setValue: forKey: en lugar de las properties del object
  • He utilizado el argumento -com.apple.CoreData.SQLDebug 1 para registrar Core Data SQL, y no se registra SQL cuando actualizo y guardo las properties del object

Realmente no entiendo tu afirmación.

 WCAAssessmentResult *result = [self currentResult]; 

De hecho, si está accediendo a una relación de muchos de un object, debería recuperar un set, no un object. De todos modos, sin ver el código es difícil de decir. El problema que está experimentando puede o no estar allí.

Prefiero esperar en tu código algo así como el siguiente fragment para acceder a objects pertenecientes a una relación de muchos. Supongo que yourObject es el object que usa para acceder a los objects WCAAssessmentResult en la relación de to-many, a la que denomino results .

 NSMutableSet *resultObjects = [yourObject mutableSetValueForKey:@"results"]; NSPnetworkingicate *pnetworkingicate = ... [resultObjects filterUsingPnetworkingicate:pnetworkingicate]; for(WCAAssessmentResult *result in resultObjects){ // modify as needed the current result object } NSError *error = nil; if (![managedObjectContext save:&error]) { NSLog(@"save failed"); NSLog(@"%@",[error description]); } 

¿Verificó que el object managedObjectContext que está utilizando para save el object es válido (no es nulo)?

Algunas ideas sin order particular:

Lograría la class del object de result y se aseguraría de que es la class que crees que es. Alguna confusión con super / sub classs podría dar como resultado que ciertos valores no se savean.

Si realizó alguna modificación en los methods setter / getter en cualquier class de la jerarquía, mire detenidamente esos methods, especialmente si utilizó un método primativeValue . Simplemente willChangeValue y didChangeValue pueden hacer que los cambios sean invisibles para el context y, a veces, para el object mismo.

managedObjectContext el context que está guardando, así como la propiedad managedObjectContext del object de result . Confirmar que son en verdad el mismo context.

Omita usando los setValue:forKey propiedad (la notación de puntos) y use setValue:forKey y vea si eso hace alguna diferencia. Si es así, tiene un problema de acceso. Del mismo modo, puede intentar setPrimativeValue:forKey para verificar también un problema de acceso.

Si tuviera que apostar, pondría mi dinero en ti asignando los objects devueltos por una búsqueda a la class incorrecta.