Как мне обновить / перезагрузить, чтобы обновить изменения в моем предикате и, таким образом, запросить выборку?

#iphone #objective-c #uitableview #nspredicate #nsfetchedresultscontroller

#iPhone #objective-c #uitableview #nspredicate #nsfetchedresultscontroller

Вопрос:

Привет, в настоящее время у меня есть табличное представление, которое заполняется с помощью Core Data.

Я ограничиваю результаты с помощью NSPredicate, чтобы в TableView отображались только элементы с одинаковым порядковым номером.

 NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                @"orderNumber == %@",     orderNumberLabel.text];
NSLog(@"predicate is: %@",predicate);
[fetchRequest setPredicate:predicate];
  

После заполнения формы для ввода заказа нажимается кнопка [сохранить заказ], после чего порядковый номер увеличивается на единицу, а также порядковый номер.

Я ожидаю, что в этом случае TableView должен быть пустым, поскольку у нового OrderNumber нет записей в базе данных sql. Однако этого не происходит, и вызов [MyTableView reloadData]; также не разрешает его.

Однако, если я выйду из проекта и повторно запущу его, у меня будет новый порядковый номер и пустой TableView. Итак, во время выполнения с запросом на выборку и установленным предикатом что-то происходит, что мне нужно попробовать и повторить с помощью вызова в моем методе saveOrderButtonPressed. Единственная проблема в том, что я не знаю, как это сделать, может кто-нибудь помочь, пожалуйста?

Иногда я также получал следующую ошибку после выхода и повторного запуска приложения после ввода заказов. Это связано с тем, что я меняю порядковый номер, но я думаю, что он исчезнет, как только я обновлю предикат / запрос выборки. Мне также нужны некоторые рекомендации по этому поводу, нужно ли мне отключать кэширование?

 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason:'FATAL ERROR: The persistent cache of section information does not match 
the current configuration.  You have illegally mutated the NSFetchedResultsController's
fetch request, its predicate, or its sort descriptor without either disabling 
caching or using  deleteCacheWithName:'
  

Ответ №1:

Вы правы, используя a NSFetchedResultsController . Это сделано именно для того, что вы описываете. Как говорится в сообщении об ошибке, вы можете установить для кэша NSFetchedResultsController значение nil для полного отключения кэширования — не большой удар по производительности, когда у вас так мало элементов. Или вы можете использовать deleteCacheWithName: с именем, которое вы присвоили кешу. Только после этого вы можете изменить запрос на выборку (например, предикат), а затем вы должны сделать performFetch: это снова. Надеюсь, у вас подключен делегат, чтобы ваше табличное представление автоматически обновлялось. Вы не говорите, что делаете какие-либо вещи, которые могут вызвать проблемы (изменение предиката, порядок сортировки и т. Д.) — Вы уверены, что нет?

Комментарии:

1. Да, я объявил делегат в заголовочном файле, а также у меня есть методы для контроллера, которые будут и будут изменять содержимое. Данные перезагружаются нормально, когда я добавляю и удаляю элементы в заказ. Я не думаю, что меняю предикат, предикат остается прежним, и я просто меняю значение, на которое он указывает, значение в OrderNumberLabel . У меня также есть порядок сортировки в соответствии с меткой времени. Теперь я установил для кэша значение nil, и это сделало свое дело. Как бы я приступил к реализации performFetch: ?

2. С вашим контроллером выбранных результатов performFetch: это то, что заставляет его отключаться и получать информацию из Core Data. Вы внимательно рассмотрели developer.apple.com/library/ios/#documentation/CoreData /… ?

3. Спасибо, Адам, я прочитал это довольно много раз, но я новичок в программировании, и требуется некоторое время, чтобы вникнуть, иногда я не уверен, правильно ли я подхожу, поэтому ваш вклад был отличным! Я нашел проблему, и теперь она работает! В начале моего кода для NSFetchedResultsController if (fetchedResultsController != nil) { return fetchedResultsController; } это означало, что остальная часть кода не будет запущена для обновления предиката 🙂 Еще раз спасибо за ваш вклад

Ответ №2:

Я нашел ответ Адама полезным — спасибо. У меня была аналогичная проблема, когда я обновлялся с помощью NSFetchedResultsControllers с общим контекстом. Данные могут быть обновлены (изменены — не добавлены или удалены) из любого из нескольких табличных представлений, но это изменение не отражается в другом представлении.

Исправление этого заключалось в вызове performFetch И reloadData в viewWillAppear. Я знаю, что это не очень эффективно — мне нужно добавить механизм, чтобы делать это только тогда, когда данные действительно были обновлены.

Ответ №3:

Вы хотите использовать NSFetchedResultsController для заполнения вашего TableView.

Вы можете реализовать методы NSFetchedResultsControllerDelegate, чтобы указать, как TableView должен обновляться в ответ на различные события.

NSFetchedResultsController отслеживает ваш запрос на выборку в фоновом режиме и вызывает свои методы делегирования в ответ на события.

Ответ №4:

У меня была похожая ситуация, когда я хотел обновить таблицу другим предикатом.

[TableView realoadData]

alone этого не сделал, но благодаря подсказке о

 (fetchedResultsController != nil) { return fetchedResultsController; } 
  

Я заставил его работать, очистив fetchResultsController перед перезагрузкой в моем случае

 _fetchedResultsController=nil;
[tableView reloadData];
  

Спасибо msek!

Комментарии:

1. Вероятно, вам также необходимо [fetchedResultsController release] перед его обнулением.