EXC_BAD_ACCESS 在部分之间移动行时
EXC_BAD_ACCESS when moving rows between sections
这是我正在尝试做的事情:
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 上显示 EXC_BAD_ACCESS 时它会崩溃没有输出到控制台的委托。
调试导航器告诉我的不多,moveRowAtIndexPath:
没有被调用。最后调用的方法是 -[UISectionRowData insertRowAtIndex:inSection:rowHeight:tableViewRowData:]
.
有时我在控制台崩溃时会收到一条奇怪的消息:
warning: could not load any Objective-C class information from the
dyld shared cache. This will significantly reduce the quality of type
information available.
我正在使用 Swift 2.
嗯,问题出在 tableView(_:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:)
方法中的一个项目的 displayOrder
中。
如果数组中有 5 个元素,而要插入的元素的 displayOrder
是 7,它会崩溃,因为该部分中的最后一个 indexPath.row
将为 5,但您正尝试使用 indexPath.row = 7
插入,这是不可能发生的。不过,您可以使用 indexPath.row = 6
插入,因为它是 table 视图中最后一个 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
}
而且效果很好。
(愚蠢的错误:-/)
这是我正在尝试做的事情:
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 上显示 EXC_BAD_ACCESS 时它会崩溃没有输出到控制台的委托。
调试导航器告诉我的不多,moveRowAtIndexPath:
没有被调用。最后调用的方法是 -[UISectionRowData insertRowAtIndex:inSection:rowHeight:tableViewRowData:]
.
有时我在控制台崩溃时会收到一条奇怪的消息:
warning: could not load any Objective-C class information from the dyld shared cache. This will significantly reduce the quality of type information available.
我正在使用 Swift 2.
嗯,问题出在 tableView(_:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:)
方法中的一个项目的 displayOrder
中。
如果数组中有 5 个元素,而要插入的元素的 displayOrder
是 7,它会崩溃,因为该部分中的最后一个 indexPath.row
将为 5,但您正尝试使用 indexPath.row = 7
插入,这是不可能发生的。不过,您可以使用 indexPath.row = 6
插入,因为它是 table 视图中最后一个 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
}
而且效果很好。
(愚蠢的错误:-/)