在节之间移动行时EXC_BAD_ACCESS

时间:2015-07-04 13:12:29

标签: ios swift uitableview exc-bad-access swift2

这是我想要做的事情:

  • UITableView处于编辑模式,包含2个部分。
  • 用户可以将第二部分的单元格移动到第一部分,反之亦然。
  • 在第一部分中,用户可以根据需要重新排序单元格。
  • 在第二部分中,单元格的定位是固定的,因此如果用户将单元格从第一部分移动到第二部分,它应该移动到特定的位置,而不是用户想要的位置。

为了实现这种行为,我有2个数组:一个用于第一部分,一个用于第二部分(不确定它是否是最佳选择)。

这是控制用户移动单元格位置的代码:

func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
    if proposedDestinationIndexPath.section == 1 {
        let item = (sourceIndexPath.section == 0 ? firstSectionItems[sourceIndexPath.row] : secondSectionItems[sourceIndexPath.row]).item
        return NSIndexPath(forRow: item.displayOrder.integerValue, inSection: 1)
    }

    return proposedDestinationIndexPath
}

以下是各部门之间移动项目的代码:

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {

    let section = (source: sourceIndexPath.section, destination: destinationIndexPath.section)

    switch section {
    case (0, 0):
        let itemToMove = firstSectionItems.removeAtIndex(sourceIndexPath.row)
        itemToMove.item.order = destinationIndexPath.row
        firstSectionItems.insert(itemToMove, atIndex: destinationIndexPath.row)
    case (1, 1):
        let itemToMove = secondSectionItems.removeAtIndex(sourceIndexPath.row)
        secondSectionItems.insert(itemToMove, atIndex: destinationIndexPath.row)
    case (1, 0):
        let itemToMove = secondSectionItems.removeAtIndex(sourceIndexPath.row)
        itemToMove.item.order = destinationIndexPath.row
        firstSectionItems.insert(itemToMove, atIndex: destinationIndexPath.row)
    case (0, 1):
        let itemToMove = firstSectionItems.removeAtIndex(sourceIndexPath.row)
        itemToMove.item.order = -1
        secondSectionItems.insert(itemToMove, atIndex: destinationIndexPath.row)
    default:
        break
    }

    DatabaseConnector.saveContext()
}

问题是,如果我在第一部分中有多个项目,并且我尝试将最后一个项目移动到第二部分,则当我将单元格放在第二部分上时它会崩溃并且在App Delegate上显示EXC_BAD_ACCESS而没有输出到控制台。 调试导航器并没有告诉我多少,moveRowAtIndexPath:没有被调用。被调用的最后一个方法是-[UISectionRowData insertRowAtIndex:inSection:rowHeight:tableViewRowData:]

有时候我在控制台崩溃时会收到一条奇怪的消息:

  

警告:无法从中加载任何Objective-C类信息   dyld共享缓存。这将显着降低类型的质量   信息。

我使用的是Swift 2。

1 个答案:

答案 0 :(得分:2)

嗯,问题发生在displayOrder方法中的tableView(_:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:)项中。

如果你有一个数组中的5个元素,而你要插入的元素的displayOrder就是7,那么它会崩溃,因为该部分中的最后一个indexPath.row将是5,但您试图插入indexPath.row = 7,这是不可能的。您可以使用indexPath.row = 6插入,因为它是表格视图中最后一个indexPath之后的下一个。

所以这就是现在的方法:

func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
    if proposedDestinationIndexPath.section == 1 {
        let item = (sourceIndexPath.section == 0 ? firstSectionItems[sourceIndexPath.row] : secondSectionItems[sourceIndexPath.row]).item
        let rowIndex = item.displayOrder > secondSectionItems.count ? secondSectionItems.count : item.displayOrder
        return NSIndexPath(forRow: rowIndex, inSection: 1)
    }

    return proposedDestinationIndexPath
}

它运作得很好。

(愚蠢的错误: - /)