Пользовательская сортировка NSFetchedResultsController не вызывается - PullRequest
8 голосов
/ 25 января 2011

В настоящее время я пытаюсь заполнить UITableView в моем проекте из Core Data, используя NSFetchedResultsController.Я использую пользовательский поиск с компаратором (хотя я также пробовал селектор и у меня была идентичная проблема):

    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    /*
     Set up the fetched results controller.
    */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"objectName" ascending:YES comparator:^(id s1, id s2) {
            NSLog(@"Comparator");
      //custom compare here with print statement
    }];
    NSLog(@"Sort Descriptor Set");
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstLetterOfObject" cacheName:@"Objects"];
    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
    if (![fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return fetchedResultsController;

Когда я захожу на эту вкладку, я вошел во всю программу и обнаружил, чтоNSFetchedResultsController даже не входит в блок компаратора при получении.Вместо этого он сортирует его с помощью некоторого метода сортировки по умолчанию.

Если я удаляю и добавляю объект с objectName, он затем входит в блок сравнения и правильно сортирует таблицу.

ПочемуNSFetchedResultsController не сортирует, используя компаратор, пока модель управляемого объекта не будет изменена?

Примечания: я также попытался отключить кэширование и / или выполнить выборку в viewDidLoad :, но кажется, что сколько раз я выбираюне важно, но когда.По какой-то причине он использует мою сортировку только после изменения объектной модели.

Ответы [ 3 ]

8 голосов
/ 25 января 2011

Есть пара вещей, о которых я могу подумать. Во-первых, хотя это может и не быть вашей проблемой, вы не можете сортировать переходные свойства. Но более вероятно, что при сортировке в модели, поддерживаемой хранилищем SQL, компаратор «компилируется» в запрос SQL, и не все функции Objective-C доступны. В этом случае вам потребуется выполнить сортировку в памяти после выполнения выборки.

РЕДАКТИРОВАТЬ: см. doc , в частности раздел «Выбор предикатов и дескрипторов сортировки».

1 голос
/ 15 ноября 2011

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

    // try to force an update for correct initial sorting bug
NSInteger count = [self.fetchedResultsController.sections count];
if (count > 0) {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
    count = [sectionInfo numberOfObjects];
    if (count > 0) {
        NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
        NSString *name = [obj valueForKey:@"name"];
        [obj setValue:@"X" forKey:@"name"];
        // Save the context.
        [self saveContext];
        [obj setValue:name forKey:@"name"];
        // Save the context.
        [self saveContext];
    }
}
0 голосов
/ 25 января 2011

Извините, но вы пропустили последнюю часть выборки для своего фрагмента кода?:

NSError *error;
BOOL success = [aFetchedResultsController performFetch:&error];

Не забудьте также отпустить запрос:

[fetchRequest release];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...