Подтвердить что ты не робот

NSFetchedResultsController: изменение предиката не работает?

Я пишу приложение с двумя таблицами на одном экране. Левая таблица - список папок, а в правой таблице показан список файлов. При нажатии на строку слева, в правой таблице будут отображаться файлы, принадлежащие этой папке.

Я использую Core Data для хранения. Когда выбор папки изменяется, предикат выборки правой таблицы NSFetchedResultsController изменится и выполнит новую выборку, а затем перезагрузит данные таблицы. Я использовал следующий фрагмент кода:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"list = %@",self.list];
[fetchedResultsController.fetchRequest setPredicate:predicate];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {   
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
[table reloadData];

Однако результаты выборки остаются теми же. У меня есть предикат NSLog'а до и после выборки, и они были верны с обновленной информацией. Результаты выборки остаются такими же, как и исходная выборка (при загрузке представления).

Я не очень хорошо знаком с тем, как Core Data извлекает объекты (есть ли система кеширования?), но раньше я делал подобные вещи (изменение предикатов, повторное извлечение данных и обновление таблицы) с помощью одиночных табличных представлений и все прошло хорошо.

Если кто-то может дать мне подсказку, я буду очень благодарен.

Спасибо заранее.

4b9b3361

Ответ 1

У меня была почти такая проблема, пока я не нашел подсказку в очень недавнем блоге в инкубаторе iphone

NSFetchedResultsController кэширует первые результаты. (Вероятно, у вас есть что-то, установленное в initWithFetchRequest: managedObjectContext: sectionNameKeyPath: cacheName)

Я предполагаю, что ваш код (например, мой) является деривацией образца CoreData, поэтому, предположив, что это @ "Root", прежде чем вы измените предикат, сделайте

[NSFetchedResultsController deleteCacheWithName:@"Root"];  

Ответ 2

В моем случае deafgreatdane ответ не работает; то, что я сделал, вероятно, наивно, но работает:

  • создать соответствующий предикат в методе configureCell:atIndexPath: (называемый tableView:cellForRowAtIndexPath:)
  • затем позвоните:
    [_fetchedResultsController.fetchRequest setPredicate:predicate];
    [_fetchedResultsController performFetch:nil];
  • обратитесь к возвращенному объекту, вызвав [self.fetchedResultsController objectAtIndexPath:indexPath]

Ответ 3

Это сработало для меня:

[NSFetchedResultsController deleteCacheWithName:nil];  
[self.fetchedResultsController.fetchRequest setPredicate:predicate]; 

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"%@, %@", error, [error userInfo]);
    abort();
}