Я не могу понять это, но у меня, похоже, есть null indexPath, когда я удаляю объект из NSFetchedResultsController
.null indexPaths при удалении объекта
Когда я удалить свой объект, я делаю это:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the object
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
[self saveContext];
}
}
Настройка NSFetchedResultsController
:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setFetchBatchSize:20];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Route" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = @[nameSort];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Routes"];
self.fetchedResultsController = aFetchedResultsController;
self.fetchedResultsController.delegate = self;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error with NSFetchedResultsController: %@", [error description]);
abort();
}
return _fetchedResultsController;
}
Это где происходит сбой:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
// Data was inserted - insert the data into the table view
case NSFetchedResultsChangeInsert: {
[self.savedRoutesTableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
// Data was deleted - delete the data from the table view
case NSFetchedResultsChangeDelete: {
[self.savedRoutesTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
case NSFetchedResultsChangeUpdate: {
SavedRoutesTableViewCell *cell = (SavedRoutesTableViewCell *)[self.savedRoutesTableView cellForRowAtIndexPath:indexPath];
[cell configureCellWithRoute:[controller objectAtIndexPath:newIndexPath]];
break;
}
case NSFetchedResultsChangeMove: {
[self.savedRoutesTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.savedRoutesTableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
default:
break;
}
}
В методе didChangeObject , оба индекса indexPath и newIndexPath равны нулю. Я могу NSLog мой объект, и я вижу объект. Он врезается в [self.savedRoutesTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
методе, за исключением:
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. *** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0] with userInfo (null)
Когда я сохранить этот объект, я откладываю это так:
self.route.name = routeName;
NSManagedObjectContext *tempContext = [self.route managedObjectContext];
[tempContext performBlock:^{
NSError *error = nil;
if (![tempContext save:&error]) {
NSLog(@"an error occurred: %@", [error localizedDescription]);
}
[self.managedObjectContext performBlock:^{
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"error in main context: %@", [error localizedDescription]);
}
}];
}];
Я не совсем уверен, где еще отлаживать это, так как NSFetchedResultsController
просто не возвращает мне indexPath для удаленного объекта. Есть предположения? Заранее спасибо.
Редактировать: Ну, я нашел виновника, вызвавшего ошибку, но я не уверен, почему это происходит. В основном у меня есть ViewController, который получает либо объект маршрута из основного MOC, если он редактирует маршрут, либо вставляет новый, если вы создаете новый маршрут. Поэтому в этом viewController, если я редактирую маршрут, потому что я пытаюсь использовать два MOC, один temp и один основной для своего родителя, поэтому я могу легко выбросить вещи, если пользователь решает отменить и не создать новый маршрут , Мне нужно было перевести этот маршрут в другой контекст, чтобы создать другой код, который у меня есть. Так что «передача» выглядит следующим образом:
NSManagedObjectContext *moc = _route.managedObjectContext;
NSManagedObjectID *routeId = [_route objectID];
self.tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
self.tempContext.parentContext = moc;
NSManagedObject *localRoute = [self.tempContext objectWithID:routeId];
self.route = localRoute;
С помощью этого кода, мое добавление на местах к существующему маршруту в настоящее время работает, что места находятся в тех же условиях, но как-то путает удаление существующего маршрута от основной MOC. Не знаете, почему и какое лучшее решение.
Так как вы догадались, почему бы не опубликовать свое решения в качестве ответа, вместо помещая его в вопрос? Это будет легче для других, чтобы найти позже. – Makoto