Серьезная ошибка приложения в основных данных с помощью fetchedResultsContainer
При попытке добавить запись появляется следующая ошибка:
Серьезная ошибка приложения. исключение был обнаружен во время изменения основных данных обработка. Обычно это ошибка в рамках наблюдателя NSManagedObjectContextObjectsDidChangeNotification. Индекс 0 недопустим с userInfo (Нуль)
И что это. Я поставил точки останова во все методы делегата fetchedResultsContainer, которые я реализовал, но ничего не сломается.
Я проследил его до:
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"titleFirstLetter" cacheName:@"Root"];
"sectionNameKeyPath" - проблема. "titleFirstLetter" - это свойство переходного процесса, в котором я создал getter для моего подкласса NSManagedObject.
Здесь получатель:
-(NSString *)titleFirstLetter
{
[self willAccessValueForKey:@"titleFirstLetter"];
NSString *aString = [[self valueForKey:@"title"] uppercaseString];
NSString *stringToReturn = [aString substringWithRange:[aString rangeOfComposedCharacterSequenceAtIndex:0]];
[self didAccessValueForKey:@"titleFirstLetter"];
return stringToReturn;
}
Когда я изменяю sectionNameKeyPath на nil, он работает, но явно не тот, который я хочу. Он также работает, когда у меня есть заголовок, уже заполненный для моей модели, так что titleFirstLetter не возвращает нуль, хотя это не похоже на проблему. Если я сделаю строку произвольной, если она равна нулю, она все равно сработает.
Любая идея, что здесь?
UPDATE:
Если я использую заголовок в разделеNameKeyPath вместо свойства переходного процесса, он не падает, но, очевидно, помещает каждый элемент в свой раздел. Так что это как-то связано с переходным свойством...
UPDATE2:
Некоторое предварительное взломание с использованием постоянного свойства вместо переходного и никаких других изменений, похоже, работает очень хорошо, поэтому это выглядит ошибкой. У меня есть отчет об ошибке: # 8553064
Update3:
Ну, поцарапай это. Использование постоянного атрибута не имело никакого значения. Сейчас я немного ухожу.
Спасибо!
Ответы
Ответ 1
Ну, это, вероятно, частично (или полностью) ошибка пользователя. Проблема заключалась в том, что в представлении, в котором я добавляю новый элемент, я поставил [self.tableView reloadData]
внутри метода viewWillAppear
. Комментируя это, не обновляли ячейки таблицы, но предотвращали сбой.
Затем я пошел вперед и отправил reloadRowsAtIndexPaths:withRowAnimation:
в представление таблицы, чтобы вручную перезагрузить несколько ячеек, которые ему нужны.
Я рад, что наконец-то!!
Ответ 2
По умолчанию выбранный контроллер результатов должен создать один раздел для каждой первой буквы sectionNameKeyPath
. Вы не должны получать один раздел за элемент, если каждый элемент не начинается с другой буквы.
Если вы хотите настроить поведение имени раздела, подкласс NSFetchedResultsController
и переопределить sectionIndexTitleForSectionName:
и sectionIndexTitles
. Подробнее см. В документах NSFetchedResultsController
.
Ответ 3
Я думал, что это моя проблема. У меня было такое же предупреждение, но мое решение было ОЧЕНЬ другим.
Вы можете получить эту ошибку, если вы неправильно внедрили все методы делегата NSFetchedResultsController. Я всегда просто копирую и вставляю 4 метода из Apple для реализации NSFetchedResultsController.
К сожалению, я пропустил один из них:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
УБЕДИТЕСЬ, ЧТО ВЫ ПОЛУЧИЛИ ЭМ, иначе вы вытащите волосы, как я.
Ответ 4
Я обнаружил другой способ прийти к такому же загадочному исключению. Мое свойство переходного процесса - например, ваше, для извлечения первой буквы - не было защищено от строки длиной 0 (@""). Попытка получить свой первый символ бросила исключение и привела к этой ошибке Core Data (а не к тому исключению, которое вы ожидали бы увидеть).
Ответ 5
Внимание!
NSFetchedResultsController * consultMessageFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[[WYCoreDataStorage shareStore] coreDataHelper] mainContext] sectionNameKeyPath:nil cacheName:nil];
Если вы используете кеш, вы должны вызвать deleteCacheWithName: перед изменением любого из запроса выборки, его предиката или дескрипторов сортировки. Вы не должны повторно использовать один и тот же выбранный контроллер результатов для нескольких запросов, если вы не установите для cacheName значение nil.