【发布时间】:2011-06-05 23:35:02
【问题描述】:
我有一个标准的拆分视图控制器,带有一个详细视图和一个表格视图。在详细视图中按下按钮可以导致对象更改其在表格视图中的排序位置。只要由此产生的排序更改不会导致添加或删除部分,这就可以正常工作。 IE。一个对象可以改变它在一个部分中的顺序或从一个部分切换到另一个部分。这些订购更改可以正常工作而不会出现问题。但是,如果对象试图移动到尚不存在的部分,或者是离开部分的最后一个对象(因此需要删除其离开的部分),则应用程序崩溃。
NSFetchedResultsControllerDelegate 具有处理添加和删除部分的方法,这些部分应在这些情况下调用。但是由于某种原因没有调用这些委托方法。
有问题的代码是样板:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"willChangeContent");
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSLog(@"didChangeSection");
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@"didChangeObject");
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"didChangeContent");
[self.tableView endUpdates];
[detailViewController.reminderView update];
}
启动应用程序,然后使最后一个对象离开一个部分会导致以下输出:
2011-01-08 23:40:18.910 Reminders[54647:207] willChangeContent
2011-01-08 23:40:18.912 Reminders[54647:207] didChangeObject
2011-01-08 23:40:18.914 Reminders[54647:207] didChangeContent
2011-01-08 23:40:18.915 Reminders[54647:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1145.66/UITableView.m:825
2011-01-08 23:40:18.917 Reminders[54647:207] Serious application error. Exception was caught during Core Data change processing: Invalid update: invalid number of sections. The number of sections contained in the table view after the update (5) must be equal to the number of sections contained in the table view before the update (6), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)
如您所见,“willChangeContent”、“didChangeObject”(移动相关对象)和“didChangeContent”都被正确调用。根据 Apple 的 NSFetchedResultsControllerDelegate 文档,“didChangeSection”应该在“didChangeObject”之前被调用,这样可以防止导致崩溃的异常。
所以我想问题是我如何确保 didChangeSection 被调用?
提前感谢您的帮助!
【问题讨论】:
标签: ipad ios core-data nsfetchedresultscontroller