Taketo Sano
Taketo Sano

Reputation: 499

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.

e.g: 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 :)

Upvotes: 3

Views: 843

Answers (3)

Taketo Sano
Taketo Sano

Reputation: 499

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

Upvotes: 3

Engnyl
Engnyl

Reputation: 1380

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.

Upvotes: 1

Puneet Sharma
Puneet Sharma

Reputation: 9484

You can also , use an NSArray to sort in your delegate method

-(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
}

Upvotes: 0

Related Questions