NSFetchedResultsController сортирует в неправильном порядке


Я работаю над проектом, основанным на примере CoreData из Xcode. У меня есть класс сущностей с именем Entity с ключом updated, который хранит метку времени обновления сущности, и NSFetchResultsController настроен на сортировку с ним в порядке убывания:

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];

Это прекрасно работает при начальной загрузке, но когда я вставляю NSManagedObject, который должен быть вставлен между другими объектами, он вставляется сверху. Когда я перезапускаю приложение, оно вставляется в правильное положение.

Например: первоначально таблица будет выглядеть следующим образом:

updated: 300
updated: 200
updated: 100

И когда я вставляю ManagedObject: updated: 250, я ожидаю, что таблица будет выглядеть так:

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

Но вот что я получаю:

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

Так ли работает NSFetchResultsController, или есть какой-либо способ повторно отсортировать все NSManagedObjects на каждой вставке? Спасибо :)

3 3

3 ответа:

Мой собственный ответ

NSManagedObject имеет свой метод isUpdated, поэтому наличие сущности с именем ключа updated было недопустимым.

Методы, которые вы не должны переопределять

NSManagedObject сам настраивает многие функции NSObject так, что управляемые объекты могут быть надлежащим образом интегрированы в основные данные инфраструктура. Основные данные зависят от реализации NSManagedObject из следующих методов, которые вы поэтому абсолютно не должны переопределение: primitiveValueForKey:, setPrimitiveValue: forKey:, isEqual:, хэш, суперкласс, класс, self, isProxy, isKindOfClass:, isMemberOfClass:, conformsToProtocol:, responstoselector:, managedObjectContext, entity, objectID, isInserted, isUpdated , isDeleted, ...

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

По умолчанию новый объект всегда вставляется сверху. Вы должны сохранить индекс каждого объекта, если хотите настроить сортировку. Тогда вы можете сортировать свои объекты любым способом.

Вы также можете использовать 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
}