以 NSException 类型的未捕获异常终止 - 删除表视图行

Posted

技术标签:

【中文标题】以 NSException 类型的未捕获异常终止 - 删除表视图行【英文标题】:terminating with uncaught exception of type NSException - delete table view row 【发布时间】:2014-06-13 21:01:19 【问题描述】:

我正在使用 Swift 开发基于表格视图的应用程序。我整天都在尝试删除一个 tableview 行,但我一直收到这个异常。不确定这是什么。这里的代码我必须删除该行。不知道还有什么要诚实的。这应该是一个简单的任务,Swift 应该让我们很容易,但这真的让我很受挫。

代码:

override func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) 
    let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext
    if editingStyle == UITableViewCellEditingStyle.Delete 
            // do something with unwrappedIndexPath.row

            context.deleteObject(myData.objectAtIndex(indexPath.row) as NSManagedObject)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

        var error: NSError? = nil
        if !context.save(&error) 
            abort()
        

    

错误:

(
    "<MyData: 0x10bba1a90> (entity: MyData; id: 0xd0000000001c0000 <x-coredata://8A0231EE-899F-48F9-953B-CAB1252FD1D0/MyData/p7> ; data: <fault>)"
)
<MyData: 0x10d84ba20> (entity: MyData; id: 0xd000000000300000 <x-coredata://8A0231EE-899F-48F9-953B-CAB1252FD1D0/MyData/p12> ; data: 
    name = test;
    skills = te;
)
Data Saved
(
    "<MyData: 0x10bba1a90> (entity: MyData; id: 0xd0000000001c0000 <x-coredata://8A0231EE-899F-48F9-953B-CAB1252FD1D0/MyData/p7> ; data: \n    name = Rob;\n    skills = Dev;\n)",
    "<MyData: 0x10bf1dec0> (entity: MyData; id: 0xd000000000300000 <x-coredata://8A0231EE-899F-48F9-953B-CAB1252FD1D0/MyData/p12> ; data: <fault>)"
)
2014-06-13 21:51:51.452 coreDataApp[2090:38878] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3185.20/UITableView.m:1487
2014-06-13 21:51:51.487 coreDataApp[2090:38878] *** 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 (2) must be equal to the number of rows contained in that section before the update (2), 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:
(
    0   CoreFoundation                      0x0000000100848e35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001022f49a0 objc_exception_throw + 45
    2   CoreFoundation                      0x0000000100848c9a +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x0000000100cdb6fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   UIKit                               0x0000000101190b3b -[UITableView _endCellAnimationsWithContext:] + 11785
    5   coreDataApp                         0x000000010000454c _TFC11coreDataApp23dataTableViewController9tableViewfS0_FTGSQCSo11UITableView_18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathGSQCSo11NSIndexPath__T_ + 2332
    6   coreDataApp                         0x0000000100004927 _TToFC11coreDataApp23dataTableViewController9tableViewfS0_FTGSQCSo11UITableView_18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathGSQCSo11NSIndexPath__T_ + 103
    7   UIKit                               0x00000001011b1e51 -[UITableView animateDeletionOfRowWithCell:] + 114
    8   UIKit                               0x00000001013409db -[UITableViewCell _swipeDeleteButtonPushed] + 60
    9   UIKit                               0x00000001010c4333 -[UIApplication sendAction:to:from:forEvent:] + 75
    10  UIKit                               0x00000001011c086d -[UIControl _sendActionsForEvents:withEvent:] + 467
    11  UIKit                               0x00000001011bfc3f -[UIControl touchesEnded:withEvent:] + 522
    12  UIKit                               0x000000010144efb7 _UIGestureRecognizerUpdate + 7670
    13  UIKit                               0x0000000101105d66 -[UIWindow _sendGesturesForEvent:] + 1041
    14  UIKit                               0x0000000101106993 -[UIWindow sendEvent:] + 667
    15  UIKit                               0x00000001010d7dd1 -[UIApplication sendEvent:] + 246
    16  UIKit                               0x00000001010e2dda _UIApplicationHandleEventFromQueueEvent + 11315
    17  UIKit                               0x00000001010bfc5f _UIApplicationHandleEventQueue + 1461
    18  CoreFoundation                      0x000000010077fbd1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    19  CoreFoundation                      0x000000010077522d __CFRunLoopDoSources0 + 269
    20  CoreFoundation                      0x000000010077485d __CFRunLoopRun + 861
    21  CoreFoundation                      0x0000000100774296 CFRunLoopRunSpecific + 470
    22  GraphicsServices                    0x0000000104462ce4 GSEventRunModal + 161
    23  UIKit                               0x00000001010c3308 UIApplicationMain + 2994
    24  coreDataApp                         0x00000001000096ad top_level_code + 77
    25  coreDataApp                         0x00000001000096ea main + 42
    26  libdyld.dylib                       0x0000000102852145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

【问题讨论】:

tableView 参数来自一个可选项,无需检查即可使用。你是如何确保它有价值的? read... 无效更新:第 0 节中的行数无效。更新 (2) 后现有节中包含的行数必须等于该节中包含的行数在更新 (2) 之前,加上或减去从该节插入或删除的行数(0 插入,1 删除),加上或减去移入或移出该节的行数(0 移入,0 移出)。 【参考方案1】:

您忘记从数据模型中删除对象

myData.removeObjectAtIndex(indexPath!.row)

这并不是真正的 Swift 问题,在 Obj-C 中也会发生同样的情况。

【讨论】:

我使用的是 NSArray 而不是 NSMutableArray @LedK 那么你应该重新考虑让它成为一个可变的。您必须从数据模型中删除该对象。这就是你的桌子正在阅读的内容,对吧?【参考方案2】:

在展开之前测试两个选项(tableView 和 indexPath)更安全:

func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath?) 
    let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext
    if editingStyle == UITableViewCellEditingStyle.Delete 
        // do something with unwrappedIndexPath.row

        if let ind = indexPath? 
            context.deleteObject(myData.objectAtIndex(ind.row) as NSManagedObject)
            tableView?.deleteRowsAtIndexPaths([ind], withRowAnimation: .Automatic)
        

        var error: NSError? = nil
        if !context.save(&error) 
            abort()
        

    

【讨论】:

仍然显示相同的异常。会不会是 myData 是 NSArray 而不是 NSMutableArray? @LedK:哎呀,我没看到另一个“!”在 indexPath 参数中。那里同样的问题。我会修改我的答案。 @LedK:关于 myData:您没有为此发布代码。我想这是一个财产。你必须告诉我们它是什么类型。 如果没有 if let ind = indexPath 和 if let tv = tableView,此代码将无法工作 我能不能把我的代码发给你,让你看看不知道怎么解释【参考方案3】:

在 tableView 数据操作中,顺序很重要。 先从数据模型中删除对象,然后删除行。

myData.removeObjectAtIndex(indexPath!.row)
tableView?.deleteRowsAtIndexPaths([ind], withRowAnimation: .Automatic)

线程有点旧,但是为了帮助其他人从搜索中获得帮助,在 swift 4 中,它看起来像这样:

myData.remove(indexPath.row)
tableView?.deleteRows(at: [indexPaths], with: .Automatic)

【讨论】:

以上是关于以 NSException 类型的未捕获异常终止 - 删除表视图行的主要内容,如果未能解决你的问题,请参考以下文章

Swift 项目以 NSException 类型的未捕获异常终止

以 NSException 类型的未捕获异常终止 - Xcode

libc+abi.dylib:以 NSException 类型的未捕获异常终止

以 NSException Timer Swift Crash 类型的未捕获异常终止

以 NSException 类型的未捕获异常终止 - 删除表视图行

线程 1 信号 SIGABRT 以 NSException 类型的未捕获异常终止