ContiguousArrayStorage 行无法识别的选择器发送到实例

Posted

技术标签:

【中文标题】ContiguousArrayStorage 行无法识别的选择器发送到实例【英文标题】:ContiguousArrayStorage row unrecognized selector sent to instance 【发布时间】:2014-10-07 01:04:22 【问题描述】:

我只需添加一个单元格并获得一个 EXC_CRASH

tableView.beginUpdates()
tableView.insertRowsAtIndexPaths([indexPathToAdd], withRowAnimation: .Automatic)
expanded = true
accordionIndex = newAccordionIndex
tableView.endUpdates()

数据源委托

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return scheme.numberOfCells


var numberOfCells: Int 
    let count = rowCountHandler!()
    return expanded ? count + 1 : count

调试后,报错在tableView.endUpdates() 这很奇怪,因为如果单元格已经存在并且我将其删除并添加到新的 indexPath,tableView.endUpdates() 没有问题。

完整方法

func handleDoubleTap(tableView: UITableView, withAbsoluteIndex index: Int) 
        if !expanded 

            // Add a cell below the double tapped cell

            let newAccordionIndex = index + 1
            let indexPathToAdd = [NSIndexPath(forRow: newAccordionIndex, inSection: 0)]
            //expanded = true
            //accordionIndex = newAccordionIndex
            //tableView.reloadData()

            tableView.beginUpdates()
            tableView.insertRowsAtIndexPaths([indexPathToAdd], withRowAnimation: .Automatic)
            expanded = true
            accordionIndex = newAccordionIndex
            tableView.endUpdates()

         else 

            if index == parentIndex  return 

            // Remove the current accordion cell & add a new one
            // below the double tapped cell

            let indexPathToRemove = NSIndexPath(forRow: accordionIndex, inSection: 0)

            let newAccordionIndex = index > accordionIndex ? index : index + 1
            let indexPathToAdd = NSIndexPath(forRow: newAccordionIndex, inSection: 0)

            tableView.beginUpdates()
            tableView.deleteRowsAtIndexPaths([indexPathToRemove], withRowAnimation: .Automatic)
            tableView.insertRowsAtIndexPaths([indexPathToAdd], withRowAnimation: .Automatic)
            accordionIndex = newAccordionIndex
            tableView.endUpdates()
        
    

我也找不到我在数组实例上调用 row 的位置。我猜是某种数组。

堆栈跟踪如下

2014-10-07 02:01:10.426 HopperBus[37542:9390828] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_TtCSs23_ContiguousArrayStorage000000007A8CFA98 row]: unrecognized selector sent to instance 0x7a84d3d0'
*** First throw call stack:
(
    0   CoreFoundation                      0x004fcdf6 __exceptionPreprocess + 182
    1   libobjc.A.dylib                     0x025b4a97 objc_exception_throw + 44
    2   CoreFoundation                      0x00504a75 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
    3   CoreFoundation                      0x0044d9c7 ___forwarding___ + 1047
    4   CoreFoundation                      0x0044d58e _CF_forwarding_prep_0 + 14
    5   UIKit                               0x01789afc -[UIUpdateItem isSectionOperation] + 52
    6   UIKit                               0x014c011f -[UITableView _endCellAnimationsWithContext:] + 5778
    7   UIKit                               0x014d771f -[UITableView endUpdatesWithContext:] + 51
    8   UIKit                               0x014d774d -[UITableView endUpdates] + 41
    9   HopperBus                           0x001440a1 _TFC9HopperBus17HBAccordionScheme15handleDoubleTapfS0_FTCSo11UITableView17withAbsoluteIndexSi_T_ + 993
    10  HopperBus                           0x0012dd2f _TFC9HopperBus19RouteViewController9tableViewfS0_FTCSo11UITableView23didSelectRowAtIndexPathCSo11NSIndexPath_T_ + 319
    11  HopperBus                           0x0012ddd5 _TToFC9HopperBus19RouteViewController9tableViewfS0_FTCSo11UITableView23didSelectRowAtIndexPathCSo11NSIndexPath_T_ + 101
    12  UIKit                               0x014d94fc -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1559
    13  UIKit                               0x014d96a7 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 285
    14  UIKit                               0x014de9a3 __38-[UITableView touchesEnded:withEvent:]_block_invoke + 43
    15  UIKit                               0x013f362e ___afterCACommitHandler_block_invoke + 15
    16  UIKit                               0x013f35d9 _applyBlockToCFArrayCopiedToStack + 415
    17  UIKit                               0x013f33ee _afterCACommitHandler + 545
    18  CoreFoundation                      0x0041ffbe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
    19  CoreFoundation                      0x0041ff00 __CFRunLoopDoObservers + 400
    20  CoreFoundation                      0x0041593a __CFRunLoopRun + 1226
    21  CoreFoundation                      0x004151ab CFRunLoopRunSpecific + 443
    22  CoreFoundation                      0x00414fdb CFRunLoopRunInMode + 123
    23  GraphicsServices                    0x06b0e24f GSEventRunModal + 192
    24  GraphicsServices                    0x06b0e08c GSEventRun + 104
    25  UIKit                               0x013c9e16 UIApplicationMain + 1526
    26  HopperBus                           0x000d44fe top_level_code + 78
    27  HopperBus                           0x000d453b main + 43
    28  libdyld.dylib                       0x02d18ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

【问题讨论】:

您能再展示一些您的UITableViewDataSource 代码吗?我的预感是您正在添加一个表格行,但没有从 tableView(_:numberOfRowsInSection:) 返回正确的值。 indexPathToAdd 是如何定义的? 通知 let indexPathToAdd = [NSIndexPath(forRow: newAccordionIndex, inSection: 0)] 所以 [indexPathToAdd] 是一个数组的数组。很遗憾类型检查器没有发现这一点:(感谢您的帮助 这基本上是因为它调用了一个没有 Swift 严格类型检查的 Objective-C API。它没有抓住它,因为insertRowsAtIndexPaths 需要一个[AnyObject] 并且[NSIndexPath] 可以转换为AnyObject 所以[[NSIndexPath]] 通过[AnyObject] 的测试。 谢谢,用你的解释回答了这个问题。还是这太具体了,应该删除? 【参考方案1】:

通知

let indexPathToAdd = [NSIndexPath(forRow: newAccordionIndex, inSection: 0)] 

所以[indexPathToAdd] 是一个数组的数组。

类型检查器没有捕捉到这一点,因为它调用了一个没有 Swift 严格类型检查的 Objective-C API。它没有抓住它,因为insertRowsAtIndexPaths 需要一个[AnyObject] 并且[NSIndexPath] 可以转换为[AnyObject] 所以[[NSIndexPath]] 通过了[AnyObject] 的测试

【讨论】:

以上是关于ContiguousArrayStorage 行无法识别的选择器发送到实例的主要内容,如果未能解决你的问题,请参考以下文章

c#命令行无错误行号

在 Clickhouse 中按运算符获取前 n 行无顺序

在 SSE2 上进行无符号 64 位比较的最有效方法是啥?

SQL Server:在具有两列的表上进行无聚合的旋转

终端快捷键使用说明

ios UIPickerView 技巧集锦(包括循环滚动)