Я новичок в разработке для iPhone (и первый вопрос опубликован здесь) и застрял с основными данными и представлениями таблиц.
Короче говоря, мое приложение падает, когда я удаляю строку из моегоUITableView из-за того, что NSFetchedResultsChangeUpdate вызывается для записи, которая уже была удалена из-за каскадного удаления в самоссылающейся таблице.
Вот описание модели данных:
Существует два объекта; Персона и Соединение .
Персона содержит имя (строка), соединения (ко многим отношениям к соединение -> источник , правило каскадного удаления) и connectedby (Отношение ко многим Соединение -> Соединение , правило каскадного удаления)
Соединение содержит отношение (строка), источник (отношение к персона -> соединения , исключить правило удаления) и соединение (отношение к Person -> connectedby , аннулировать правило удаления)
Идея состоит в том, что есть два человека, связанных отношениями (например, Мать или Сын )
В моем TableViewController я реализую следующее:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
и
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
Person *person = nil;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
person = (Person *)[fetchedResultsController objectAtIndexPath:indexPath];
[self configureCell:(PersonTableViewCell *)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
person = (Person *)[fetchedResultsController objectAtIndexPath:indexPath];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
и
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
Здесьпримеры записей, которые я создал для тестирования этого:
Person *person1 = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
[person1 setName:[NSString stringWithFormat: @"Tommy"]];
Person *person2 = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
[person2 setName:[NSString stringWithFormat: @"Jane"]];
Connection *connection = [NSEntityDescription insertNewObjectForEntityForName:@"Connection" inManagedObjectContext:managedObjectContext];
[connection setConnection:person2];
[connection setSource:person1];
[connection setRelationship:[NSString stringWithFormat:@"Mother"]];
Connection *connection2 = [NSEntityDescription insertNewObjectForEntityForName:@"Connection" inManagedObjectContext:managedObjectContext];
[connection2 setConnection:person1];
[connection2 setSource:person2];
[connection2 setRelationship:[NSString stringWithFormat:@"Son"]];
Когда я удаляю запись в indexPath [0,0], т.е. Джейн в этом примере, так как представление отсортировано по имени, я генерирую следующую ошибку:
2010-10-19 16:09:01.461 HelpMe[6324:207]
Serious application error.
Exception was caught during Core Data change processing.
This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.
*** -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0] with userInfo (null)
Detected an attempt to call a symbol in system libraries that is not present on the iPhone:
_Unwind_Resume called from function -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] in image CoreData.
Кажется, что удаление правильно генерирует NSFetchedResultsChangeDelete для indexPath [0,0], но также сразу генерирует NSFetchedResultsChangeUpdate для [0,1], который больше не существует, так как [0,1], по-видимому, теперь в [0,0] после удаления.
Без соответствующей записи Connection удаляется нормально.
Казалось бы, я могу обойти эту проблему, просто вызвав [self.tableView reloadData] для controllerDidChangeContentвместо реализации обновлений start / end и didChangeOnject: но я не верю, что это правильный способ справиться с этим.
Я ценю любую помощь, которую кто-либо может предложить.