java - 在 for 循环中解构时尝试调用空对象
问题描述
这怎么可能?
在后台线程上,我正在运行一些填充列表的计算,然后使视图无效,并且视图运行 onDraw。
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
。这怎么可能?我的列表是非空的,我从来没有将列表设置为空。如果它为空,则 for 循环永远不会运行。我在这里重新创建了运行问题的代码,但无法复制它,但它在我的应用商店中很少发生。
知道可能发生什么吗?
解决方案
多线程可能是罪魁祸首。想象一下,当这段代码运行时,您的列表中有一些项目:
val listCopy = ArrayList(list)
当 ArrayList 构造函数从列表中复制项目时,另一个线程会清除列表,这会将所有内容标记为空。如果另一个线程清除列表的速度比该线程复制引用的速度快,它将开始为列表中的最后一项复制空引用。
如果您要从多个线程修改数据,我建议专门使用只读列表。
推荐阅读
- swift - CollectionView 多个部分标题行
- eiffel - OS X 上的 Eiffel 故障 - Eiffel 找不到库
- scapy - 数据包没有被我在 python 中使用 scapy 模块创建的程序过滤
- ibm-cloud - 使用 Mulesoft (Mule 4) 使用 IBM MQ 时的身份验证问题
- json - 我无法在 React Native 中返回解析信息
- python - 如何在 Python Kivy 应用程序中打开 pdf?
- asp.net - ASP.NET Core 会话超时
- html - Django:如果我开始一个表,然后有一个 {% block %}{% endblock %} 并在之后关闭表,它会破坏表吗?
- javascript - 单击单选按钮时如何处理?
- android - 安卓。图像视图未在某些设备上显示