2010-08-06 10 views
6
if (win) { 
    // Game was won, set completed in puzzle and time 
    // Calculate seconds taken 
    int timeTaken = (int)([NSDate timeIntervalSinceReferenceDate] - self.gameStartTime); 
    int bestTime = [[self.puzzle valueForKey:@"bestTime"] intValue]; 
    if (timeTaken < bestTime && bestTime != 0) { 
     [self.puzzle setValue:[NSNumber numberWithInt:timeTaken] forKey:@"bestTime"]; 
     NSLog(@"Best time for %@ is %@", [self.puzzle valueForKey:@"name"], [self.puzzle valueForKey:@"bestTime"]); 
    } 
} 

Este es un código de un juego de iPad que estoy creando y estoy utilizando Core Data para almacenar los niveles. Cuando se completa y gana un nivel, quiero establecer el mejor tiempo para ese nivel. Se calcula el tiempo necesario y, si es mejor que el mejor tiempo anterior, quiero establecerlo como el mejor momento para el nivel.Entidad no es un valor clave que cumple con la codificación de la clave

Este código falla en la línea 'int bestTime' cuando intenta recuperar el mejor tiempo de self.puzzle que es un NSManagedObject de Core Data. El mejor momento se almacena como un Entero 32 en el modelo de Datos básicos. Falla con un error SIGABRT.

'[<NSManagedObject 0x95334d0> valueForUndefinedKey:]: the entity Puzzle is not key value coding-compliant for the key "bestTime".' 

He buscado en línea por razones de por qué esto está sucediendo y cómo solucionarlo, pero nada parece haber ayudado. Hay otros lugares en los que accedo a valores enteros desde el modelo Core Data y funcionan perfectamente, aunque se usan para filtrar y ordenar consultas.

Tampoco sé si funcionará la línea donde establecí el valor.

Cualquier ayuda sobre esto sería muy apreciada.

EDITAR: Este es el código que obtiene una serie de acertijos de los cuales uno se toma como el acertijo anterior.

// Define our table/entity to use 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Puzzle" inManagedObjectContext:managedObjectContext]; 

// Setup the fetch request 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
[request setEntity:entity]; 

// Set the filter for just the difficulty we want 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"difficulty == %d", difficulty]; 
[request setPredicate:predicate]; 

// Define how we will sort the records 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortid" ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 
[request setSortDescriptors:sortDescriptors]; 
[sortDescriptor release]; 

// Fetch the records and handle an error 
NSError *error; 
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; 
+0

¿Es 'bestTime' una propiedad que agregó a su modelo más tarde? Es decir. ¿Podría ser esto un problema de migración? –

+0

Lo agregué más tarde, pero eliminé la aplicación del simulador y la reinstalé. – danpalmer

+0

También reinicié el contenido y la configuración del simulador y todavía no funciona. Mismo error que antes. – danpalmer

Respuesta

14

Ok, En primer lugar, me gustaría agradecer a todos los que sugirieron ideas. Es posible que no me hayan ayudado a resolver el problema, pero aprendí más sobre Core Data y siempre es bueno saber qué debo verificar cuando las cosas no funcionan.

Realmente no sé cuál era el problema. Hasta esta mañana tuve Xcode abierto durante aproximadamente 5 días, y ayer agregué el atributo 'mejor tiempo' al modelo de datos. Solo puedo suponer que durante los 5 días, Xcode se había vuelto un poco inestable y pensó que se salvaría cuando no lo era. Había comprobado que había guardado los atributos del modelo, de hecho, debo haber comprobado 3 o 4 veces, así como mi hábito de pulsar Comando + S después de cualquier cambio que realice.

De todos modos, reinicié mi máquina hoy temprano y cuando inicié Xcode hace unos minutos me di cuenta de que 'besttime' no estaba en el archivo de modelo. Lo agregué, restablecí las configuraciones en el simulador de iPad y funcionó.

Gracias a todos nuevamente por la ayuda, lo siento, la solución no fue más interesante y basada en código. Aunque me hace sentir mejor que mi código no sea la causa.

+0

He estado viendo este problema mucho recientemente y la mayoría de las veces parece ser causado por el paquete de la aplicación en el simulador que conserva un antiguo archivo .mom de una versión anterior del modelo de datos. Por alguna razón, no siempre se purga cuando cambia el modelo. Reiniciar la máquina hizo que el simulador construyera un directorio de aplicaciones completamente nuevo, lo que resolvió el problema. Eliminar la aplicación del simulador también lo arreglará. – TechZen

+0

He intentado eliminar la aplicación en el simulador. El problema era en realidad con Xcode pensando que había puesto el atributo 'bestTime', pero que en realidad no lo había hecho. – danpalmer

+1

Reiniciar OS X ayudado. Gracias. Reiniciar Xcode, limpiar el código o eliminar la aplicación del dispositivo no ayudó. Al reiniciar Xcode después del reinicio de OS X, la diferencia del modelo era evidente, y esta vez se comportó. ¡Gracias por la pista! –

11

Ese objeto gestionado no tiene un atributo llamado "bestTime". De acuerdo con el mensaje de excepción, definitivamente es un Puzzle, por lo que no ha declarado un atributo llamado bestTime en su modelo (o lo ha escrito mal o lo ha escrito en mayúsculas de manera diferente).

+0

Definí 'besttime' en el archivo xcdatamodel en mi proyecto al igual que todas las otras cosas a las que estoy accediendo. Intenté copiar y pegar el nombre directamente de ese archivo. – danpalmer

+0

¿Está definitivamente en la misma entidad a la que intenta acceder? – Joshua

+0

Sí. He colocado algunos registros antes de la línea que no puede imprimir otros atributos que sé que funcionan. He comparado el resultado con lo que debería ser y es el mismo modelo. – danpalmer

1

No creo que haya suficiente información aquí para determinar la causa. Puede intentar leer el Core Data Troubleshooting Guide; una causa posible podría ser si inicializaste esta instancia particular de Puzzle usando plain init en vez de initWithEntity.

+0

Echaré un vistazo a eso. Gracias. En cuanto a la inicialización, no sé. Ejecuté una solicitud de búsqueda en el contexto de mi objeto gestionado y puse los resultados en un diccionario mutable. El objeto simplemente se toma de eso en función del cual se presiona tableviewcell. – danpalmer

+0

danpalmer: edite su pregunta para incluir la solicitud de búsqueda. –

1

Si agregó el atributo bestTime al modelo en el momento posterior, es posible que haya olvidado poner declaración e implementación para ellos en la Clase de objetos gestionados conectada.

Pruebe las acciones de conveniencia proporcionadas en Diseño -> Modelo de datos -> Copiar Objetivo-C ... Declaraciones de métodos/Implementaciones al portapapeles (al editar su archivo de modelo).

+0

Puzzle no es una clase que he escrito heredando de NSManagedObject, es solo un NSManagedObject. Por lo que he leído sobre Core Data, esta es una buena forma de hacerlo si no tienes ningún código que deba ejecutarse en el objeto. Para mí, es simplemente una colección de propiedades. Eso es todo. – danpalmer

2

Resolví el mismo problema al eliminar y crear de nuevo el modelo de datos, limpiar y volver a compilar. Creo que el error se debe a que los datos centrales no actualizan algunos datos a veces.

0

Si analiza JSON en un objeto administrado, asegúrese de estar utilizando la propiedad coreDataPropertyName en lugar de la clave json-key-name de JSON. Fácil de mezclar cuando se nombran de manera similar.

Este error me estaba volviendo loco, y todo porque estaba usando image-url en lugar de imageURL.

Cuestiones relacionadas