尝试从 UITableView 中删除行时断言失败
Posted
技术标签:
【中文标题】尝试从 UITableView 中删除行时断言失败【英文标题】:Assertion failure when trying to delete a row from UITableView 【发布时间】:2013-01-30 03:29:53 【问题描述】:当我尝试使用 UITableViewCellEditingStyleDelete 从 UITableView 中删除一行时出现断言失败。希望有人能告诉我我的代码出了什么问题。
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:1070
2013-01-30 14:19:21.450 MyApp[48313:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) 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 (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(0x28ee012 0x1d3fe7e 0x28ede78 0x19fef35 0xf51b8d 0xf5df95 0xf5dfc3 0xcfe9 0xf6c384 0x10a9b1b 0x1d53705 0xeb3920 0xeb38b8 0xf74671 0xf74bcf 0xf746a6 0x1144f95 0x1d53705 0xeb3920 0xeb38b8 0xf74671 0xf74bcf 0xf73d38 0xee333f 0xee3552 0xec13aa 0xeb2cf8 0x2d1adf9 0x2d1aad0 0x2863bf5 0x2863962 0x2894bb6 0x2893f44 0x2893e1b 0x2d197e3 0x2d19668 0xeb065c 0x24fd 0x2435)
libc++abi.dylib: terminate called throwing an exception
(lldb)
这是我的代码:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [records count];
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
if (editingStyle == UITableViewCellEditingStyleDelete)
// Delete record from the sqlite database
NSNumber *recordDBID = [records objectAtIndex:indexPath.row];
Record *myRecord = [[Record alloc] initWithDBID:recordDBID database:UIAppDelegate.formManager.connection];
BOOL valueX = [myRecord deleteRecordInDb:recordDBID];
[myRecord release];
// Delete record from array
NSMutableArray *aNewArray = [[NSMutableArray alloc] initWithArray:records];
[aNewArray removeObjectAtIndex:indexPath.row];
records = aNewArray;
[aNewArray release];
// Delete the record from the table
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[tableView reloadData];
【问题讨论】:
该错误表明您正在从records
中删除两个对象。在您从中删除对象之前,通过记录 records
来检查您的对象是否没有从数组中删除。
【参考方案1】:
我认为您可能过于复杂地删除表格视图行。
您确实不需要如果您只想删除这两个调用之间的一行,则需要调用[tableView beginUpdates]
和[tableView endUpdates]
,因此您可能会丢失它们。仅当您要同时执行多个插入或删除操作时才需要开始和结束更新。
其次,此时调用[tableView reloadData]
是多余的,因为表视图将使用分配的委托/数据源自动请求它作为删除操作的一部分所需的信息。您可以将代码的最后一部分简化为:
//从表中删除记录
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
可能是当前的行删除代码(结合更广泛的代码库)使系统感到困惑。
如果上述方法没有帮助,我们需要查看 records
数组被修改的所有代码。在这种情况下,我会更新我的答案。
【讨论】:
谢谢特雷伯。现在我知道 beginUpdates 和 endUpdates 做了什么。最后,我不得不放弃使用 deleteRowsAtIndexPaths。我从数据库中删除记录,通过再次查询数据库来更新数组(而不是使用 removeObjectAtIndex 从中删除记录),然后使用 [self.tableView reloadData] 更新 UITableView。 为了进一步简化情况,您可以在调用“deleteRowsAtIndexPaths”之前将“记录”设为 NSMutableArray,然后从数组中删除对象。 另外,当您尝试通过创建中间可变数组并删除对象来从数组中删除记录时,认为您遇到了内存管理问题。然后,您释放此数组,以便根据引用计数规则,您创建的新数组现在将被释放。这可能与稍后返回到“UITableView”的行数不正确有关。【参考方案2】:就我而言,我有错别字:在insertRowsAtIndexPaths
中是indexPath
而不是newIndexPath
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?)
switch type
case .Insert:
self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Bottom)
case .Delete:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
case .Update:
self.tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Move:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Bottom)
【讨论】:
以上是关于尝试从 UITableView 中删除行时断言失败的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3.0 无法从 UITableView 中删除一行
UITableView _endCellAnimationsWithContext:无故断言失败
iOS 7 上的 -[UITableView layoutSublayersOfLayer:] 中的断言失败