NSFetchedResultsController sorts in wrong order

I am working on a project based on the CoreData example from Xcode. I have a entity-class named Entity with a updated key which stores the timestamp that the entity was updated, and the NSFetchResultsController is set to sort with it in descending order:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Entity" inManagedObjectContext:_managedObjectContext]];
[fetchRequest setFetchBatchSize:20];
[fetchRequest setSortDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"updated" ascending:NO]]];

NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_managedObjectContext sectionNameKeyPath:nil cacheName:nil];

This works fine on the initial load, but when I insert a NSManagedObject that should be inserted in between the other objects, it gets inserted at the top. When I relaunch the app, it gets inserted at the right position.

eg: initially the table would look like:

updated: 300
updated: 200
updated: 100

and when I insert a ManagedObject: updated: 250 , I expect the table to look like:

updated: 300
updated: 250 <-- inserted here
updated: 200
updated: 100

but this is what I get:

updated: 250 <-- inserted at the top
updated: 300
updated: 200
updated: 100

Is this how NSFetchResultsController works, or is there any way to re-sort all NSManagedObjects on every insert? Thanks :)


My own answer

NSManagedObject has it's method isUpdated , so having the entity with a key name updated was invalid.

Methods you Must Not Override

NSManagedObject itself customizes many features of NSObject so that managed objects can be properly integrated into the Core Data infrastructure. Core Data relies on NSManagedObject's implementation of the following methods, which you therefore absolutely must not override: primitiveValueForKey:, setPrimitiveValue:forKey:, isEqual:, hash, superclass, class, self, isProxy, isKindOfClass:, isMemberOfClass:, conformsToProtocol:, respondsToSelector:, managedObjectContext, entity, objectID, isInserted, isUpdated , isDeleted, ...

http://developer.apple.com/library/ios/#documentation/cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/Reference/NSManagedObject.html


In default, a new object would always be inserted to the top. You should keep an index of every objects if you would like to customize the sort. Then you can sort your objects in any way.


你也可以使用NSArray来排序你的委托方法

-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
  NSArrary *resultsArray = [controller allObjects];
  // sort 
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"updated" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [reultsArray sortedArrayUsingDescriptors:sortDescriptors];
  // reload table using this array
}
链接地址: http://www.djcxy.com/p/36134.html

上一篇: UISearchDisplayController + NSFetchedResultsController更新footerView

下一篇: NSFetchedResultsController排序顺序错误