简体   繁体   中英

Sorting Core Data results into NSFetchedResultsController

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM