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