NSExpressionDescription for empty result sets
Using Core Data, I have a fetch request to fetch the minimum of a certain attribute using an expression. If I set a predicate on the request that results in no results being matched, I get EXC_BAD_ACCESS. This makes some sense, seeing as you can't add nil to an NSArray for the results, but what's the best way around this?
I can just use a sort order and a fetch limit of 1, but it seems a bit of the oversigh开发者_如何学Ct in the NSExpressionDescription API that there's no way to return a default result or return an empty array if no objects were matched before evaluating the expression.
Or am I misdiagnosing the EXC_BAD_ACCESS entirely, and NSExpressionDescriptions, used in setPropertiesToFetch on a fetch request should already behave sensibly for this situation?
Ran into a similar situation today. Set your NSFetchRequest resultType to NSDictionaryResultType.
- (NSDate *)maxDateForEvent:(Event *)event withContext:(NSManagedContext *)context
{
NSExpression *modifiedDateExpression = [NSExpression expressionForKeyPath:@"modifiedDate"];
NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:"
arguments:[NSArray arrayWithObject:modifiedDateExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"maxDate"];
[expressionDescription setExpression:maxExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
fetch.entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
fetch.propertiesToFetch = [NSArray arrayWithObject:expressionDescription];
fetch.resultType = NSDictionaryResultType;
fetch.predicate = [NSPredicate predicateWithFormat:@"event == %@", event];
NSError *error;
NSArray *array = [context executeFetchRequest:fetch error:&error];
if (!array || ![array count]) {
return [NSDate distantPast];
}
NSDate *date = [[array lastObject] objectForKey:@"maxDate"];
if (!date) {
return [NSDate distantPast];
}
return date;
}
The workaround in the second paragraph is what I've had to use, so this appears to just be an API oversight.
精彩评论