Viv*_*ive 12 objective-c tableview nsfetchedresultscontroller ios
在swype删除期间(此方法的大多数importatnt行):
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
Table *deleteRow = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:deleteRow];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Run Code Online (Sandbox Code Playgroud)
删除行时出现此错误:
由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第2节中的行数无效.更新
后的现有部分中包含的行数(1)必须等于该行中包含的行数在更新(1)之前的部分,加上或减去从该部分插入或删除的行数(0插入,1删除)和加或减移入或移出该部分的行数(0移入,0移动)出)."
如果我评论最后一行代码([tableView deleteRowsAtIndexPaths:...])一切正常(但我必须刷新视图才能看到该行被删除).
怎么做得好......?
编辑:考虑@Kyr Dunenkoff回应我添加:
- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
UITableView *tableV = [self tableView];
switch(type) {
case NSFetchedResultsChangeDelete:
[tableV deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller
{
[[self tableView] endUpdates];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller
{
[[self tableView] beginUpdates];
}
Run Code Online (Sandbox Code Playgroud)
但是这并没有改变崩溃和错误.它只是导致添加新行不再起作用.
Kyr*_*off 14
为了正确地执行此操作,实现controller:didChangeObject:方法,在其中switch为不同的更改类型创建,在NSFetchedResultsChangeDelete插入您的情况下[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];.因为当您使用NSFetchedResultsController等数据源时,所有更改都必须来自那里,而您的表只反映它们.此外,还可以实现controller:willChangeContent和controller:didChangeContent,把[tableView beginUpdates]成willChange和[tableView endUpdates]成didChange.
问题是 - 正如你通过评论发现的那样 - 你的最后一行:
[tableView deleteRowsAtIndexPaths:...
Run Code Online (Sandbox Code Playgroud)
苹果表视图编程指南告诉你需要这样做,但实际上你不应该在使用NSFetchedResultsController时.NSFetchedResultsController的想法是它负责更新UI以使其与模型保持同步,这样您就不需要了.因此,如果您只是从模型中删除对象,则获取的结果控制器将处理其余部分.
[更新]哎呀,不完全正确我刚才所说的.获得结果控制器不会在没有帮助的情况下"照顾其余".它的代表将负责其余部分,但有人需要实现它的委托.我习惯于在Standford CS193p课程中包含CoreDataTablewViewController辅助类,它只是一个UITableViewController子类,它实现了NSFetchedResultsController文档中推荐的所有方法.最重要的是,它实现了在模型更改时更新表视图的委托方法.
因此,您更新的方法仍然是正确的:您不应该将deleteRowsAtIndexPaths ..放在导致用户删除它们的代码中,而是让获取的结果控制器驱动该进程,并实现委托实际执行它.
(在这里获取帮助类:http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2011-fall,并观看第14讲以了解如何使用它)
| 归档时间: |
|
| 查看次数: |
10583 次 |
| 最近记录: |