In my first attempt at using NSExpression in a fetch request, I’m getting a result that is consistently one off from 开发者_开发技巧what I get if I use a regular fetch request.
The MO “Subject” has a to-many relationship to the MO “Book,” the inverse being to-one.
This is the NSExpression fetchRequest I’m using:
Project_AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@“Book”
inManagedObjectContext:context];
Subject *subjectToDelete = [self.arrayOfSubjects objectAtIndex:indexSelected];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"subject == %@", subjectToDelete];
NSExpression *expn = [NSExpression expressionForFunction:@"count:"
arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"idPerm"]]];
NSExpressionDescription *expnDesc = [[NSExpressionDescription alloc] init];
[expnDesc setExpression:expn];
[expnDesc setName:@“countMatchingBooks”];
[expnDesc setExpressionResultType:NSInteger64AttributeType];
NSArray *properties = [NSArray arrayWithObject:expnDesc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setPredicate:pred];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if (error) {
// error handling here
}
[request release];
[expnDesc release];
// Retrieve the count from the results array.
NSNumber *numBooksAssignedSubjectToDelete = [[results objectAtIndex:0] valueForKey:@“countMatchingBooks”];
uint64_t uloloBooksAssignedSubjectToDelete = [numBooksAssignedSubjectToDelete unsignedLongLongValue];
(The idea is to present the user with a confirmation panel advising them of how many Books will be deleted via the Cascade rule if they choose to delete the chosen Subject — without faulting the Book MOs at this point.)
And this is the simple fetchRequest I’m using as a test:
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@“Book”
inManagedObjectContext:contextMain];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSError *error = nil;
NSArray *booksAll = [contex executeFetchRequest:request error:&error];
[request release];
// Loop through the “booksAll” array and count those whose subject matches the one assigned as “subjectToDelete”
What happens is that if the NSExpression fetchRequest returns a count of n, the simple fetchRequest returns a count of n + 1.
Thinking the fetchRequests themselves might be somehow altering the data, I tried running them in a different order, but with the same result.
Maybe requests using expressions skip MOs which have not yet been saved? No. I ran a test that creates a bunch of new “Book” MOs to see if the gap between expression request and regular request would widen. It remained exactly one off.
Any idea what I’m doing wrong?
NSFetchRequests using NSExpressionDescription does not include unsaved objects. NSFetchRequest has a method -setIncludePendingChanges:, which does not accept YES when the result type is NSDictionaryResultType. This means that you cannot use NSExpressionDescription to get unsaved objects.
精彩评论