为什么 IndexPath 在 clouser 中不同
Why IndexPath is different in clouser
我有自定义 CollectionView
单元格,点击按钮我正在调用 closure
,这是在 cellForItem
下实现的
下面是代码
cell.closeImageTappped = { [weak self] cell in
guard let strongSelf = self else {
return
}
if let objectFirst = strongSelf.selectedFiles.first(where: {[=10=].fileCategory == cell.currentSelectedCellType && [=10=].fileName == cell.currentObject?.fileName}) {
cell.imgPicture.image = nil
cell.imgPlusPlaceHolder.isHidden = false
objectFirst.removeImageFromDocumentDirectory()
strongSelf.selectedFiles.remove(at: strongSelf.selectedFiles.index(where: {[=10=].fileName == objectFirst.fileName})!)
strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
strongSelf.collectionViewSelectFile.performBatchUpdates({
strongSelf.collectionViewSelectFile.deleteItems(at: [indexPath])
}, completion: nil)
}
}
应用在某些情况下会崩溃,比如我按下关闭多个单元格的速度太快
这里崩溃
strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
fatal error: Index out of range
当我检查行时
▿11个元素
- 0 : 0
- 1 : 1
- 2 : 2
- 3 : 3
- 4 : 4
- 5 : 5
- 6 : 6
- 7 : 7
- 8 : 8
- 9 : 8
- 10 : 8
而 IndexPath 是
po indexPath
▿ 2 elements
- 0 : 0
- 1 : 11
如果我得到这样的 indexPath,它会显示正确的 IndexPath
self?.collectionViewSelectFile.indexPath(for: cell)
▿ Optional<IndexPath>
▿ some : 2 elements
- 0 : 0
- 1 : 9
但为什么 IndexPath
与 self?.collectionViewSelectFile.indexPath(for: cell)
不同
indexPath
来自闭包外部,因此它的值是在闭包分配给单元格时捕获的。假设您的数组中有 10 个项目,您删除了第 9 个项目。您的数组现在有 9 个项目,但是显示第 10 个项目的单元格(但现在是第 9 个项目 - 数组中的索引 8)对于 indexPath.row
仍然有 9 个,而不是 8 个,所以您得到一个数组当您尝试删除最后一行时越界。
为避免此问题,您可以在闭包内的集合视图上使用 indexPath(for:)
以确定单元格的当前 indexPath
:
cell.closeImageTappped = { [weak self] cell in
guard let strongSelf = self else {
return
}
if let objectFirst = strongSelf.selectedFiles.first(where: {[=10=].fileCategory == cell.currentSelectedCellType && [=10=].fileName == cell.currentObject?.fileName}),
let indexPath = collectionView.indexPath(for: cell) {
cell.imgPicture.image = nil
cell.imgPlusPlaceHolder.isHidden = false
objectFirst.removeImageFromDocumentDirectory()
strongSelf.selectedFiles.remove(at: strongSelf.selectedFiles.index(where: {[=10=].fileName == objectFirst.fileName})!)
strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
strongSelf.collectionViewSelectFile.performBatchUpdates({
strongSelf.collectionViewSelectFile.deleteItems(at: [indexPath])
}, completion: nil)
}
}
我有自定义 CollectionView
单元格,点击按钮我正在调用 closure
,这是在 cellForItem
下面是代码
cell.closeImageTappped = { [weak self] cell in
guard let strongSelf = self else {
return
}
if let objectFirst = strongSelf.selectedFiles.first(where: {[=10=].fileCategory == cell.currentSelectedCellType && [=10=].fileName == cell.currentObject?.fileName}) {
cell.imgPicture.image = nil
cell.imgPlusPlaceHolder.isHidden = false
objectFirst.removeImageFromDocumentDirectory()
strongSelf.selectedFiles.remove(at: strongSelf.selectedFiles.index(where: {[=10=].fileName == objectFirst.fileName})!)
strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
strongSelf.collectionViewSelectFile.performBatchUpdates({
strongSelf.collectionViewSelectFile.deleteItems(at: [indexPath])
}, completion: nil)
}
}
应用在某些情况下会崩溃,比如我按下关闭多个单元格的速度太快
这里崩溃
strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
fatal error: Index out of range
当我检查行时
▿11个元素 - 0 : 0 - 1 : 1 - 2 : 2 - 3 : 3 - 4 : 4 - 5 : 5 - 6 : 6 - 7 : 7 - 8 : 8 - 9 : 8 - 10 : 8
而 IndexPath 是
po indexPath
▿ 2 elements
- 0 : 0
- 1 : 11
如果我得到这样的 indexPath,它会显示正确的 IndexPath
self?.collectionViewSelectFile.indexPath(for: cell)
▿ Optional<IndexPath>
▿ some : 2 elements
- 0 : 0
- 1 : 9
但为什么 IndexPath
与 self?.collectionViewSelectFile.indexPath(for: cell)
indexPath
来自闭包外部,因此它的值是在闭包分配给单元格时捕获的。假设您的数组中有 10 个项目,您删除了第 9 个项目。您的数组现在有 9 个项目,但是显示第 10 个项目的单元格(但现在是第 9 个项目 - 数组中的索引 8)对于 indexPath.row
仍然有 9 个,而不是 8 个,所以您得到一个数组当您尝试删除最后一行时越界。
为避免此问题,您可以在闭包内的集合视图上使用 indexPath(for:)
以确定单元格的当前 indexPath
:
cell.closeImageTappped = { [weak self] cell in
guard let strongSelf = self else {
return
}
if let objectFirst = strongSelf.selectedFiles.first(where: {[=10=].fileCategory == cell.currentSelectedCellType && [=10=].fileName == cell.currentObject?.fileName}),
let indexPath = collectionView.indexPath(for: cell) {
cell.imgPicture.image = nil
cell.imgPlusPlaceHolder.isHidden = false
objectFirst.removeImageFromDocumentDirectory()
strongSelf.selectedFiles.remove(at: strongSelf.selectedFiles.index(where: {[=10=].fileName == objectFirst.fileName})!)
strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
strongSelf.collectionViewSelectFile.performBatchUpdates({
strongSelf.collectionViewSelectFile.deleteItems(at: [indexPath])
}, completion: nil)
}
}