在for循环中进行析构函数时,尝试对null对象进行调用



这怎么可能?

在一个后台线程上,我正在运行一些计算,它填充一个列表,然后使一个视图无效,然后该视图在Draw上运行。

var list = mutableListOf<Pair<DataPoint, String>>()

generateBgData() {
list.clear()
list.add(...,...)
invalidate()
}

在onDraw中,我复制了列表,以防止对列表的更新导致错误,

val listCopy = ArrayList(list)
for ((point, str)in listCopy) { // Null exception thrown here
canvas.drawText(...)
}

但在注意到的行中,我在销毁java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object kotlin.Pair.component1()' on a null object reference时得到了一个空对象引用错误。这怎么可能呢?我的列表是非null的,我从来没有将列表设置为null。如果它为空,则for循环永远不应该运行。我在这里重新创建了运行该问题的代码,无法复制,但这种情况在我的应用程序play store中很少发生。

知道可能会发生什么吗?

多线程可能是罪魁祸首。想象一下,当这个代码运行时,你的列表中有一些项目:

val listCopy = ArrayList(list)

当ArrayList构造函数从列表中复制项时,另一个线程会清除列表,该列表将所有项标记为null。如果另一个线程清除列表的速度比这个线程复制引用的速度快,那么它将开始为列表中的最后一项复制空引用。

如果您正在修改来自多个线程的数据,我建议您只使用只读列表。

最新更新