无法删除分区中的行

Posted

技术标签:

【中文标题】无法删除分区中的行【英文标题】:Can't delete row in section 【发布时间】:2015-01-21 20:56:25 【问题描述】:

我在删除部分中的单元格时遇到了问题。tableViewController 有三个部分,其中包含不同的单元格。如果我尝试删除一个单元格,调试器将显示:

2015-01-23 20:22:15.105 等级 - Zensurenverwaltung[23854:5674475] * -[UITableView _endCellAnimationsWithContext:]、/SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m 中的断言失败: 1566 2015-01-23 20:22:15.133 等级 - Zensurenverwaltung[23854:5674475] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:无效的节数。更新后表视图中包含的节数(3)必须等于更新前表视图中包含的节数(3),加上或减去插入或删除的节数(0插入,1已删除)。 *** 首先抛出调用堆栈: ( 0 CoreFoundation 0x00000001008bef35 异常预处理+ 165 1 libobjc.A.dylib 0x00000001025adbb7 objc_exception_throw + 45 2 CoreFoundation 0x00000001008bed9a +[NSException raise:format:arguments:] + 106 3 基础 0x0000000100d565df -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195 4 UIKit 0x00000001013c98ff -[UITableView _endCellAnimationsWithContext:] + 10935 5 级 - Zensurenverwaltung 0x00000001000fa0c2 _TFC26Grade___Zensurenverwaltung28TestTypesTableViewController9tableViewfS0_FTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 3618 6 级 - Zensurenverwaltung 0x00000001000fa207 _TToFC26Grade___Zensurenverwaltung28TestTypesTableViewController9tableViewfS0_FTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 87 7 UIKit 0x00000001013edcb4-[UITableView animateDeletionOfRowWithCell:] + 130 8 UIKit 0x00000001013ce125 __52-[UITableView _swipeActionButtonsForRowAtIndexPath:]_block_invoke + 72 9 UIKit 0x00000001012f68be-[UIApplication sendAction:to:from:forEvent:] + 75 10 UIKit 0x00000001013fd410-[UIControl_sendActionsForEvents:withEvent:] + 467 11 UIKit 0x00000001013fc7df-[UIControl touchesEnded:withEvent:] + 522 12 UIKit 0x00000001016a3540 _UIGestureRecognizerUpdate + 9487 13 UIKit 0x000000010133bff6-[UIWindow_sendGesturesForEvent:] + 1041 14 UIKit 0x000000010133cc23 -[UIWindow 发送事件:] + 667 15 UIKit 0x00000001013099b1 -[UIApplication 发送事件:] + 246 16 UIKit 0x0000000101316a7d _UIApplicationHandleEventFromQueueEvent + 17370 17 UIKit 0x00000001012f2103 _UIApplicationHandleEventQueue + 1961 18 核心基础 0x00000001007f4551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 19 核心基础 0x00000001007ea41d __CFRunLoopDoSources0 + 269 20 核心基础 0x00000001007e9a54 __CFRunLoopRun + 868 21 核心基础 0x00000001007e9486 CFRunLoopRunSpecific + 470 22 图形服务 0x00000001052fd9f0 GSEventRunModal + 161 23 UIKit 0x00000001012f5420 UIApplicationMain + 1282 24 级 - Zensurenverwaltung 0x00000001001e164e top_level_code + 78 25 级 - Zensurenverwaltung 0x00000001001e168a 主要 + 42 26 libdyld.dylib 0x0000000102d87145 开始 + 1 27 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib:以 NSException 类型的未捕获异常终止

我就是不明白……

这是我的代码:

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    var indexes: NSMutableIndexSet = NSMutableIndexSet()
    dataTestType = context.executeFetchRequest(fetchRequestForTestType, error: nil) as [TestType]

    if editingStyle == UITableViewCellEditingStyle.Delete 

        context.deleteObject(dataTestType[indexPath.row] as NSManagedObject)
        context.save(nil)
        dataTestType.removeAtIndex(indexPath.row)

        if dataTestType.count == 0 
            indexes.addIndex(indexPath.section)
        

        tableView.beginUpdates()
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        tableView.deleteSections(indexes, withRowAnimation: .Fade)
        tableView.endUpdates()
    

谁能帮帮我?

非常感谢!

【问题讨论】:

究竟是哪一行代码导致了崩溃? commitEditingStyle 函数内的这一行:context.deleteObject(dataTestType[indexPath.row] as NSManagedObject) 您知道这不是您使用 Core Data 删除的方式,对吧?您必须从托管对象上下文中删除、保存并停止。然后你会在 NSFetchedResultsControllerDelegate 方法中被回调,这就是你更新 UI 的地方。 尝试按以下顺序调用:context.deleteObject(dataTestType[indexPath.row] as NSManagedObject) dataTestType.removeAtIndex(indexPath.row) 【参考方案1】:

您从dataTestType 数组中删除indexPath.row 处的对象

 dataTestType.removeAtIndex(indexPath.row)

在下一行,您尝试在同一索引处获取对象,但如果您删除了数组中唯一的对象,它将不存在:

context.deleteObject(dataTestType[indexPath.row] as NSManagedObject)

您可以通过重新排序这两行来简单地解决问题。

正如 matt 所指出的,您也可以使用 NSFetchedResultsController,因为建议在 UITableView 中显示核心数据记录。那么你根本不需要dataTestType 数组。现在你每次调用commitEditingStyle 方法时调用context.executeFetchRequest。如果您要获取许多记录,它效率低下并且可能导致性能不佳。

【讨论】:

然后我又遇到了一个错误。我会更新我的问题! 这个错误意味着删除对象后,您仍然从数据源中的 tableView:numberOfRowsInSection: 方法返回 1。我们也能看到这个方法的实现吗?此外,如果您有很多部分,如果它不包含任何行,则可能必须删除该部分,请参阅此答案:***.com/a/1001239/2128900 您是否尝试过我之前评论中提出的解决方案?当您删除该部分的最后一行时,似乎您已经删除了该部分。 好的,我试过了,但是有一个新的错误...我会再次更新我的帖子。 您还必须更改numberOfSectionsInTableView 方法,以便在删除部分后返回正确的值。

以上是关于无法删除分区中的行的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:无法删除列表中的行

我无法删除主视图控制器中的行

无法删除数据框 python 3 中的行。值错误:真值不明确

无法使用 ORACLE APEX 删除交互式报表中的行

Firebase + Swift:无法删除 tableView 中的行

错误:无法通过行访问已删除的行信息