Reputation: 32091
I have an entity Tag
with string property tagName
. I went to fetch all objects in this Entity into a NSFetchedResultsController
, but I want Tag with tagName
"Main" to be the first object. Here's what I'm doing now:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *lastDescriptor2 =
[[[NSSortDescriptor alloc] initWithKey:@"tagName" ascending:NO comparator:^NSComparisonResult(NSString* tag1, NSString* tag2) {
NSLog(@"compare");
if ([tag1 isEqualToString:@"main"]) return NSOrderedAscending;
if ([tag2 isEqualToString:@"main"]) return NSOrderedDescending;
return [tag1 compare:tag2];
}] autorelease];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor2]];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
self.fetchedResultsController.delegate=self;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
This code is called in my viewDidLoad
method, and is only called once. The first time it's called, for some reason the sortDescriptor here doesn't apply - it just doesn't get called (the NSLog
statement doesn't show up either). My results are returning solely based on the BOOL
value I specify for ascending
- the block is ignored.
But when I insert a new Tag
object into the MOC
and the NSFetchedResultsController
update delegate methods are called, the actual sortDescriptor gets applied, and the NSLog(@"compare")
finally appears, but only when I make updates to the objects! No matter what I've tried, I can't get the sort to apply to the initial fetch.
Any ideas at all?
Upvotes: 3
Views: 656
Reputation: 5290
As you have probably seen at one point or another, if the predicate you pass into your NSFetchRequest is a block predicate, your fetch request will fail. This happens because CoreData needs to translate your predicate into SQL so it can run it against the database. The result is that a predicate is never actually compared against the objects that result from the fetch request.
The same is true of sort descriptors. The fetch request does not perform the comparison against the objects when the fetch is performed. It is passed as part of the SQL.
You also describe an interesting exception to the rules I describe above. When you have an existing NSFetchedResultsController and add an object to the NSManagedObjectContext, the NSFetchedResultsController is updated by evaluating the NSPredicate and NSSortDescriptor against the object, rather than converting them to SQL.
Upvotes: 1