开发者

NSPredicate compare string less than other string

EDIT: Ignore this question. I was not looking at my test-data properly. My code below works. But there are some good answers to look at. Thanks!

For convenience we store all our data as strings in core data. Now I want to fetch all objects of an entity that has a timestamp older than a specified timestamp (oldDate). That means I want to do a compare with NSPredicate so the NSFetchRequest returns objects that has a timestamp less than the specified timestamp. The following obviously does not work but it is the best I have come up with this far.

- (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",filtere开发者_如何学JAVAdObjects.count);
    for (NSManagedObject * nsObject in filteredObjects) {
        [context deleteObject:nsObject];
    }
}

}

I hope you understand what I mean. It's a bit hard to explain.


If you can support blocks, then you can write the predicate like this:

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

All that does is make an NSDate out of your string (assuming that it's a timestamp since 1970), and then check to see if the time interval since the oldDate is less than zero, indicating that it's before the oldDate. Amend the inequality to suit your logic.


If the timestamps are stored as seconds since a reference date, such as the unix epoch, then you can use:

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

Check the NSDate documentation, these instance methods return NSTimeInterval which is actually just a double.


You could change your core data entity so it stores a date instead of a string that represents a date.

This would make this very easy.


It would depend on how the dates are stored, for example "2010-02-17" or seconds since 1970, but I guess adding a transient property would be the easiest solution (next to changing the date property, which you said you can't do).

A transient property is a data model property that is not saved in the database, but is computed every time. So you could make a transient Integer property, which is computed from your string value. See "A Better Solution" on 2pi.dk/tech/cocoa/transient_properties.html for information about making such a getter function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜