NSPredicate сравнивает строку меньше, чем другая строка - PullRequest
1 голос
/ 17 февраля 2011

РЕДАКТИРОВАТЬ: игнорировать этот вопрос.Я не смотрел на свои тестовые данные должным образом.Мой код ниже работает.Но есть несколько хороших ответов.Спасибо!

Для удобства мы храним все наши данные в виде строк в основных данных.Теперь я хочу получить все объекты объекта, у которого временная метка старше указанной временной метки (oldDate).Это означает, что я хочу сделать сравнение с NSPredicate, чтобы NSFetchRequest возвращал объекты, у которых временная метка меньше указанной временной метки.Следующее, очевидно, не работает, но это лучшее, что я нашел на этом пути.

- (void)deleteRecordsOlderThan:(NSString*)oldDate {
    NSError *error = nil;   
    NSFetchRequest *request =[[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:tableName inManagedObjectContext:context]];
    [request setIncludesPropertyValues:NO];
    [request setIncludesPendingChanges:YES];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"timestamp < %@)",oldDate];
    NSLog(@"Predicate: %@",predicate);
    [request setPredicate:predicate];

    NSArray *filteredObjects = [context executeFetchRequest:request error:&error];
    [request release];
    if (error) {
        NSLog(@"Error fetching objects for deletion: %@", [error description]);
        return;
    }
    NSLog(@"Number of old objects to delete:%d",filteredObjects.count);
    for (NSManagedObject * nsObject in filteredObjects) {
        [context deleteObject:nsObject];
    }
}

}

Надеюсь, вы понимаете, о чем я.Это немного сложно объяснить.

Ответы [ 4 ]

3 голосов
/ 17 февраля 2011

Если вы можете поддерживать блоки, то вы можете написать предикат следующим образом:

NSPredicate *predicate = [NSPredicate predicateWithBlock:^(id evaluatedObject, NSDictionary *bindings) {
    return ([[NSDate dateWithTimeIntervalSince1970:[[evaluatedObject timestamp] doubleValue] timeIntervalSinceDate:oldDate] < 0);
}];

Все, что нужно, это сделать NSDate из вашей строки (при условии, что это временная метка с 1970 года), а затемпроверьте, является ли интервал времени с oldDate меньше нуля, указывая, что это до oldDate.Исправьте неравенство в соответствии с вашей логикой.

0 голосов
/ 17 февраля 2011

Если временные метки хранятся в секундах с контрольной даты, такой как эпоха Unix, то вы можете использовать:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"timestamp < %@)", [NSString stringWithFormat:@"%lf", [oldDate timeIntervalSince1970]]];

Проверьте NSDate документацию , эти методы экземпляра возвращают NSTimeInterval, который на самом деле просто удваивается.

0 голосов
/ 17 февраля 2011

Это будет зависеть от того, как хранятся даты, например, «2010-02-17» или секунд с 1970 года, но я думаю, что добавление переходного свойства было бы самым простым решением (рядом с изменением свойства даты, которое вы сказали вы не можете сделать).

Переходное свойство - это свойство модели данных, которое не сохраняется в базе данных, но вычисляется каждый раз. Таким образом, вы можете создать временное свойство Integer, которое вычисляется из вашего строкового значения. См. «Лучшее решение» на 2pi.dk/tech/cocoa/transient_properties.html для получения информации о создании такой функции получения.

0 голосов
/ 17 февраля 2011

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

Это сделает это очень легко.

...