首页 > 解决方案 > 如果我在旋转设备“释放对象的校验和不正确”时调用“insertRows”,UITableView 会崩溃

问题描述

我必须解析大量数据才能在我的 Tableview 中显示。

因此,我不是解析所有数据然后重新加载表视图,而是解析 50 行数据并插入它们。

因此,用户可以立即看到一些东西,而我则继续解析其余数据并每次插入 50 个以上。

如果我不旋转设备,这非常有效,但如果我在仍在添加数据时旋转,我的应用程序会崩溃。

这是我添加数据并检查是否添加了 50 行数据:

self.comments.append(currentComment)

indexPathsToAdd.append(IndexPath(row: self.comments.count - 1, section: 1))

if self.comments.count % 50 == 0 {
    self.addRowsIfNeeded(indexPathsToAdd: indexPathsToAdd)
    indexPathsToAdd.removeAll()
}

这是我插入行的方法:

func addRowsIfNeeded( indexPathsToAdd : [IndexPath]){
        if indexPathsToAdd.count > 0 {
            DispatchQueue.main.async {
                self.myTableView.beginUpdates()
                self.myTableView.insertRows(at: indexPathsToAdd, with: .fade)
                self.myTableView.endUpdates()
            }
        }
    }

错误信息通常是:

*** Assertion failure in -[APPNAME.GodTableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore/UIKit-3698.84.15/UITableView.m:2055 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1.  The number of rows contained in an existing section after the update (150) must be equal to the number of rows contained in that section before the update (127), plus or minus the number of rows inserted or deleted from that section (50 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

但有时我也会收到这个奇怪的错误,我不知道这意味着什么:

malloc:已释放对象 0x1509c7000 的校验和不正确:可能在被释放后修改。损坏值:0x71

标签: iosswiftuitableviewautolayoutmalloc

解决方案


您的问题是您正在更新数据源数组self.comments,但在插入 50 条附加注释之前不插入行。想必你的numberOfRowsInSection回报self.comments.count

假设在开始插入行之前,数组有 100 个元素。

当您旋转设备时,它会导致 tableview 重新加载,调用numberOfRowsInSection- 返回的行数包括您已添加到数组中但尚未调用的行insertRows。然后,这将成为表视图中行数的新计数(从您的异常消息来看,这是 127)。

当你最终调用时insertRows,你会得到一个异常,因为表视图认为你应该有127+50 = 177行,但数组只包含100+50 = 150.

我建议您将新注释添加到临时数组中,直到您准备好实际插入行。这样numberOfRowsInSection将返回正确的数字:

var newComments = [Comment]()
var indexPathsToAdd = [IndexPath]()

// ...

newComments.append(currentComment)

indexPathsToAdd.append(IndexPath(row: self.comments.count + newComments.count - 1, section: 1))

if newComments.count % 50 == 0 {
    DispatchQueue.main.async {
        self.myTableView.beginUpdates()
        self.comments.append(contentsOf:newComments)
        self.myTableView.insertRows(at: indexPathsToAdd, with: .fade)
        self.myTableView.endUpdates()
    }
    newComments.removeAll()
    indexPathsToAdd.removeAll()
}

推荐阅读