Ios 为什么IndexPath在clouser中不同

Ios 为什么IndexPath在clouser中不同,ios,swift,uicollectionview,indexpath,Ios,Swift,Uicollectionview,Indexpath,我有一个自定义的CollectionView单元格,我正在点击按钮调用closure,它在cellForItem 下面是代码 cell.closeImageTappped = { [weak self] cell in guard let strongSelf = self else { return } if let objectFirst = strongSelf.selectedFiles.first(whe

我有一个自定义的
CollectionView
单元格,我正在点击按钮调用
closure
,它在
cellForItem

下面是代码

  cell.closeImageTappped  = { [weak self] cell in
        guard let strongSelf = self else {
            return
        }


        if let objectFirst = strongSelf.selectedFiles.first(where: {$0.fileCategory == cell.currentSelectedCellType && $0.fileName == cell.currentObject?.fileName}) {
            cell.imgPicture.image = nil

            cell.imgPlusPlaceHolder.isHidden = false
            objectFirst.removeImageFromDocumentDirectory()
            strongSelf.selectedFiles.remove(at: strongSelf.selectedFiles.index(where: {$0.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)
致命错误:索引超出范围

当我检查行时

▿ 11要素 - 0 : 0 - 1 : 1 - 2 : 2 - 3 : 3 - 4 : 4 - 5 : 5 - 6 : 6 - 7 : 7 - 8 : 8 - 9 : 8 -10:8

而indexath是

xpath
▿ 2要素
- 0 : 0
-1:11

如果我得到这样的indexPath,它将显示正确的indexPath

self?.collectionViewSelectFile.indepath(for:cell)
▿ 可选的
▿ 一些:2个要素
- 0 : 0
-1:9


但是为什么
indepath
self?.collectionViewSelectFile.indepath(for:cell)
indepath
来自闭包外部,因此它的值在闭包分配给单元格时被捕获。假设您的数组中有10项,您删除了第9项。您的数组现在有9个项目,但显示第10个项目(但现在是第9个项目-数组中的索引8)的单元格中仍然有9个用于
indexPath.row
,而不是8个,因此在尝试删除最后一行时,会出现数组边界冲突

为了避免此问题,您可以在闭包内的集合视图上使用
indepath(for:)
,以确定单元格的当前
indepath

cell.closeImageTappped  = { [weak self] cell in

        guard let strongSelf = self else {
            return
        }


        if let objectFirst = strongSelf.selectedFiles.first(where: {$0.fileCategory == cell.currentSelectedCellType && $0.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: {$0.fileName == objectFirst.fileName})!)
            strongSelf.arraySource[indexPath.section].rows.remove(at: indexPath.row)
            strongSelf.collectionViewSelectFile.performBatchUpdates({
                strongSelf.collectionViewSelectFile.deleteItems(at: [indexPath])

            }, completion: nil)
        }

    }

不相关的,但那个软弱的自我,坚强的自我又是为了什么?如果
self
曾经是
nil
,您将无法按下该按钮,因为它将离开屏幕。使用
[无主自我]
绝对安全。关于这个问题,我想在删除单元格后索引路径没有正确更新。
indepath
来自哪里?“它是从封闭之外来的吗?”瓦迪安说,“但是,那个软弱的自我,那个坚强的自我,来来回回是为了什么?”?你是对的,我想假设长时间运行的任务正在clouser内部进行,在它被执行之前,用户按下后退按钮,所以我使用了弱self,我猜删除单元格后索引路径没有正确更新有什么建议吗?@Paulw11正如我在问题中提到的,此闭包位于
cellForItem
delegate中method@Paulw11我的删除代码正确吗
strongSelf.collectionViewSelectFile.performBatchUpdates({
是异步任务,在执行完成之前多次按是否存在此问题?谢谢,我已经找到了问题中提到的解决方案,我只想知道您解释得很好的原因:D