2010-11-21 7 views
7

Estoy tratando de obtener resultados de mi entidad "MeterReading", que tiene dos propiedades, "timestamp" y "reading". "marca de tiempo" es un NSDate. Ahora estoy tratando de buscar un objeto con una fecha exacta.Usando NSPredicate para obtener NSDate exacto de NSManagedObjectContect

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MeterReading" inManagedObjectContext:context]; 
[request setEntity:entity]; 
NSLog(@"%f", [self.timestamp timeIntervalSince1970]); 

NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp == %@", self.timestamp]; 
NSLog(@"%@", pre); 
[request setPredicate:pre]; 

Ahora, self.timestamp se pasa a otro ViewController de antemano, la NSLog muestra:

1290264372,210091

El NSPredicate registra

timestamp == CAST (311957172.210091, "NSDate")

Primera pregunta: ¿Por qué los dos números no son iguales?

Segunda y más importante pregunta: en ManagedContext, tengo cuatro entradas con fechas. Si uso "< =" en lugar de "==", obtengo resultados con una fecha más pequeña que la que aprobé, incluida la que deseo tener. ¿Por qué no puedo obtener la única fecha con el operador "=="? ¿Esto puede estar relacionado con la precisión de mis fechas?

Gracias!

Respuesta

3

Este es el mismo problema que las comprobaciones de igualdad de coma flotante inherentemente inseguras. A medida que los valores de punto flotante se pasan, se convierten, se usan en aritmética, etc., pierden precisión poco a poco. Puede que tenga que usar un predicado más complejo que en su lugar verifica las fechas dentro de una cierta tolerancia; por ejemplo,

NSArray *timestamps = [NSArray arrayWithObjects: 
    [self.timestamp dateByAddingTimeInterval:-1], 
    [self.timestamp dateByAddingTimeInterval:1], 
    nil 
]; 

NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp BETWEEN %@", timestamps]; 

la que le conseguiría ningún objeto que coinciden con la fecha más o menos de un segundo.

+0

que casi funcionó, ¡gracias! al pasar la matriz apareció un error, pero pasé dos nsdates manualmente al predicado y ahora funciona. :) – denbec

+0

Oops, perdón por eso! Me alegro de que ayudó, sin embargo. –

+0

Tenga en cuenta que este ejemplo no funcionará con los datos centrales. Necesitas usar algo como esto: http://zdam.posterous.com/core-data-fetch-by-date – SpaceTrucker

3

Primera pregunta: ¿Por qué los dos números no son iguales?

Internamente, NSDate parece almacenar una marca de tiempo con respecto a 1 de enero de 2001 y no el 1 de enero de 1970. El número 311957172.210091 probablemente es el número de segundos desde el 01/01/2001.

¿Por qué no puedo obtener una sola fecha con el operador "=="? ¿Esto puede estar relacionado con la precisión de mis fechas?

No lo sé. ¿Ha inspeccionado el archivo SQLite directamente para ver qué marcas de tiempo se almacenan allí?

+0

obtengo la marca de tiempo de mi tienda, la paso a otro controlador de vista e intento eliminarla allí. por lo tanto, estoy tratando de buscar el mismo objeto; Pasé la marca de tiempo de antemano. eso es lo extraño. ¿hay alguna otra forma de eliminar un objeto gestionado sin obtener ese objeto de antemano? – denbec

+0

¿Por qué pasas la marca de tiempo y no el objeto en sí? No hay necesidad de buscarlo de nuevo. –

1

Para su primera pregunta, apuesto a los números coincidirán si utilizó [self.timestamp timeIntervalSinceReferenceDate] en lugar de desde 1970.

a su segunda pregunta, mi impresión es que la fecha en el almacenamiento de objeto administrado no es exactamente el mismo que self.timestamp. Por ejemplo, ¿podría ser que la fecha almacenada solo contenga un día y no un tiempo? Es posible que debas hacer un redondeo para que coincidan.

+0

En realidad, estoy usando la marca de tiempo o la fecha directamente desde el objeto administrado, lo paso a otro controlador de vista, hago otras cosas y quiero eliminarlo de nuevo. por lo tanto, necesito que el objeto lo elimine del contexto, y no conozco otra forma de eliminar un objeto antes de recuperarlo nuevamente. así que debería ser la misma fecha que estoy usando. – denbec

Cuestiones relacionadas