8

我试图在 Core Data 的特定属性中找到最旧的日期。我在 Core Data Programming Guide 中找到了一个示例,声称可以做到这一点,但是当我运行它时不断收到无法识别的选定错误。

我的代码(与 Apple 示例相比只有很小的更改):

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext: ctx];
[request setEntity:entity];

// Specify that the request should return dictionaries.
[request setResultType:NSDictionaryResultType];

// Create an expression for the key path.
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"startedAt"];

// Create an expression to represent the minimum value at the key path 'creationDate'
NSExpression *minExpression = [NSExpression expressionForFunction:@"min:" arguments:[NSArray arrayWithObject:keyPathExpression]];

// Create an expression description using the minExpression and returning a date.
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];

// The name is the key that will be used in the dictionary for the return value.
[expressionDescription setName:@"minDate"];
[expressionDescription setExpression:minExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];

// Set the request's properties to fetch just the property represented by the expressions.
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

// Execute the fetch.
NSError *error;
NSArray *objects = [ctx executeFetchRequest:request error:&error];

和错误:

-[NSCalendarDate count]: unrecognized selector sent to instance ...

这很奇怪,因为 1)NSCalendarDate 已被弃用,并且 2)我绝对不会调用 count。

非常感激任何的帮助!

4

2 回答 2

16

为什么不只是添加一个排序描述符以按startedDate升序排序,然后只让 fetch 请求返回 1 个对象?

于 2010-05-10T21:57:50.267 回答
0

这是我的代码,它确实有效。我看不出与您自己的代码有任何显着差异,也许它在核心数据模型的定义中。确保您的日期是 NSDate 并且已编入索引。

- (NSDate *)lastSync:(PHAssetMediaType)mediaType {
    NSEntityDescription *entity = [NSEntityDescription  entityForName:kMediaItemEntity inManagedObjectContext:self.managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.entity = entity;
    fetchRequest.resultType = NSDictionaryResultType;

    NSMutableArray *predicates = [NSMutableArray array];
    [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaType,mediaType]];
    [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaProviderType,self.mediaProviderType]];
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: predicates];
    fetchRequest.predicate = predicate;

    // Create an expression for the key path.

    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:kSyncTime];
    // Create an expression to represent the function you want to apply

    NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:"
                                                            arguments:@[keyPathExpression]];

    // Create an expression description using the maxExpression and returning a date.
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    [expressionDescription setName:@"maxDate"];
    [expressionDescription setExpression:maxExpression];
    [expressionDescription setExpressionResultType:NSDateAttributeType];

    // Set the request's properties to fetch just the property represented by the expressions.
    fetchRequest.propertiesToFetch = @[expressionDescription] ; // @[kSyncTime];

    NSError *fetchError = nil;
    id requestedValue = nil;

    // fetch stored media
    NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
    if (fetchError || results == nil || results.count == 0) {
        return [NSDate dateWithTimeIntervalSince1970:0];
    }
    requestedValue = [[results objectAtIndex:0] valueForKey:@"maxDate"];
    if (![requestedValue isKindOfClass:[NSDate class]]) {
        return [NSDate dateWithTimeIntervalSince1970:0];
    }
    DDLogDebug(@"sync date %@",requestedValue);
    return (NSDate *)requestedValue;
}
于 2015-10-15T08:03:06.947 回答