2010-11-21 2 views
7

Я пытаюсь получить результаты моей сущности «MeterReading», которая имеет два свойства: «метка времени» и «чтение». «timestamp» - это NSDate. Теперь я пытаюсь получить объект с точной датой.Использование NSPredicate для получения точного NSDate из 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]; 

Теперь self.timestamp передается другому ViewController заранее, то NSLog показывает:

1290264372,210091

NSPredicate журналы

метку времени == CAST (311957172.210091, "NSDate")

Первый вопрос: почему два числа не совпадают?

Второй и более важный вопрос: в ManagedContext у меня есть четыре записи с датами. Если я использую «< =» вместо «==», я получаю результаты с датой, меньшей той, которую я прошел, включая ту, которую я хочу иметь. Почему я не могу получить одну единственную дату с оператором «==»? Может ли это быть связано с точностью моих дат?

Спасибо!

ответ

3

Это та же проблема, что и проверка равенства с плавающей запятой, которая по своей сути является небезопасной. Поскольку значения с плавающей запятой передаются, преобразуются, используются в арифметике и т. Д., Они постепенно теряют точность. Возможно, вам придется использовать более сложный предикат, который вместо этого проверяет даты в пределах определенного допуска; например,

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

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

, который предоставит вам любые объекты, соответствующие вашей дате плюс или минус одна секунда.

+0

что почти сработало, спасибо! передача массива привела к ошибке, но я передал два nsdates вручную в предикат, и теперь он работает. :) – denbec

+0

К сожалению, об этом! Рад, что это помогло. –

+0

Обратите внимание, что этот пример не будет работать с данными ядра. Вам нужно использовать что-то вроде этого: http://zdam.posterous.com/core-data-fetch-by-date – SpaceTrucker

3

Первый вопрос: почему два номера не совпадают?

Внутри NSDate кажется для хранения временных меток по отношению к 1 января 2001 года, а не 1 января 1970 года Число 311957172.210091, вероятно, это число секунд, прошедших с 01.01.2001.

Почему я не могу получить единственную дату с оператором «==»? Может ли это быть связано с точностью моих дат?

Я не знаю. Вы проверили файл SQLite напрямую, чтобы узнать, какие временные метки там хранятся?

+0

Я получаю временную метку из своего магазина, передаю ее другому контроллеру представления и пытаюсь удалить ее там. поэтому я пытаюсь получить один и тот же объект; Я заранее пропустил метку времени. это странно. Есть ли другой способ удалить управляемый объект, не получив этот объект заранее? – denbec

+0

Почему вы передаете временную метку вокруг, а не сам объект? Не нужно забирать его снова. –

1

Для вашего первого вопроса, я уверен, что цифры будут совпадать, если вы использовали [self.timestamp timeIntervalSinceReferenceDate] вместо с 1970 года

Для Вашего второго вопроса, то я подозреваю, что дата в управляемом хранилище объекта не является точно таким же, как self.timestamp. Например, может быть, что хранимая дата содержит только день, а не время? Возможно, вам нужно будет округлить, чтобы они соответствовали друг другу.

+0

На самом деле, я использую временную метку или дату непосредственно из управляемого объекта, передаю его другому контроллеру представления, делаю некоторые другие вещи и хочу удалить его снова. поэтому мне нужен объект, чтобы удалить его из контекста, и я не знаю другого способа удалить объект перед его извлечением. так, это должна быть та же самая дата, которую я использую. – denbec

Смежные вопросы