NSFetchedResultsController: изменение предиката не работает? - PullRequest
35 голосов
/ 20 марта 2010

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

Я использую 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 извлекает объекты (есть ли система кеширования?), Но я уже делал подобные вещи раньше (изменяя предикаты, повторно выбирая данные и обновляя таблицу) с использованием отдельных представлений таблицы и все прошло хорошо.

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

Заранее спасибо.

Ответы [ 4 ]

56 голосов
/ 22 марта 2010

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

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

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

[NSFetchedResultsController deleteCacheWithName:@"Root"];  
1 голос
/ 28 сентября 2018

У меня была похожая проблема в моем быстром проекте. Это сработало для меня

NSFetchedResultsController.deleteCache(withName: fetchedResultsController.cacheName)

1 голос
/ 18 мая 2016

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

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

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"%@, %@", error, [error userInfo]);
    abort();
} 
1 голос
/ 02 ноября 2015

В моем случае ответ Глухого Великана не работает; то, что я сделал вместо этого, вероятно, наивно, но работает:

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