Как я могу решить "CoreData: ошибка: серьезная ошибка приложения" в результате слияния iCloud?
Итак, я был на последних этапах тестирования моего приложения, и теперь я столкнулся с проблемой, которая поставила меня в тупик.
Процесс выглядит следующим образом:
1) Измените через coredata на "Основной стол", который связан с myTableView
в первом ViewController
2) Как часть вышеприведенного кода, я также удаляю все предыдущие объекты и сохраняю строку в "Sync Log Table". В результате в этой таблице должен остаться один объект, например, строка "Пн 20:33".Примечание: это недавно реализованная функция, и я считаю, что она является источником проблемы. Я хочу, чтобы она использовалась для заполнения метки на всех устройствах для отображения последних синхронизированных данных, другими словами, предоставляя пользователю возможность легко убедитесь, что все устройства имеют одинаковую информацию и обновлены
3) Оба изменения затем сохраняются путем вызова [managedObjectContext save:&error];
4) На втором устройстве все работает нормально, и я могу внести изменения в "Основную таблицу", которые отображаются на myTableView
после вызова кода для перезагрузки.
Обратите внимание, у меня было 3 строки, показывающие в myTableView
на втором устройстве, и изменение, которое было выполнено на шаге 1 для "Основной таблицы", не изменит представление таблицы на втором устройстве из-за предиката, который фильтрует результаты.
Тогда проблема начинается
5) Второе устройство начинает получать изменения через iCloud и метод делегата:
- (void)mergeiCloudChanges:(NSNotification*)note forContext:(NSManagedObjectContext*)moc {
NSLog(@"AppDelegate Merge icloud changes for context");
//***Specifically the line below!!
[moc mergeChangesFromContextDidSaveNotification:note];
NSNotification* refreshNotification = [NSNotification notificationWithName:@"RefreshAllViews" object:self userInfo:[note userInfo]];
[[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
}
Строка, указанная выше в коде, запускает следующие методы в моем firstViewController
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"I'm inside the method Controller Will Change Context");
[self.myTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@"I'm inside the method Controller did Change Object");
UITableView *tableView = self.myTableView;
switch(type) {
// And enters in this line here
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
Тогда я получаю ошибку:
CoreData: error: Serious application error.
An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.
Invalid update: invalid number of rows in section 0.
The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (3), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)
После получения этой ошибки myTableView больше не реагирует, он не будет обновлять или отвечать, например, на удаление для удаления.
В основном, насколько я понимаю, объекты, которые объединяются из "таблицы журнала синхронизации", вставляются (когда их не должно быть) в методы делегата myTableView, которые должны получать объекты только из "главной таблицы", таким образом, выбрасывая счетчик и вызывая ошибку.
Есть идеи, как решить эту проблему в моих обстоятельствах? Любая помощь будет принята с благодарностью
1 ответ
Ваши объекты табличного представления (т. Е. Контроллер выборки или NSArray, что угодно) должны быть обновлены перед вызовом insertRowsAt…
или же deleteRowsAt…
на самом столе. Табличное представление говорит вам, что числа не складываются в соответствии с тем, что он ожидает - если вы используете контроллер выборки, возможно, после того, как вы позвоните [moc mergeChangesFromContextDidSaveNotification:note]
Вам необходимо отправить сообщение сохранения в moc или принудительно обновить объекты данных табличного представления.