android - Android 的 MutableLiveData 应该只使用可为空的对象吗?
问题描述
我的简化代码是:
class MyViewModel : ViewModel() {
private val myLiveData: MutableLiveData<MyObject> = MutableLiveData<MyObject>(MyObject())
val myObject: MutableLiveData<MyObject>
get() = myLiveData
fun addItem(item: MyItem) {
val value = myLiveData.value // value is of nullable type MyObject?
// MyObject contains a list of other objects
(value?.myList as MutableList).add(item)
myLiveData.value = value!! // Here I get a IDE warning or error
}
}
如果我在第 9 行留下非空运算符 (!!),Android Studio 会给我一个警告:
Unnecessary non-null assertion (!!) on a non-null receiver of type MyObject
如果我在第 9 行删除非空运算符 (!!),Android Studio 会给我一个错误:
Expected non-nullable value
在 Kotlin 中处理这个问题的正确方法是什么?如果我MyObject?
在第 2 行和第 3 行使用可空值,Android Studio 似乎喜欢它,但我真的不打算让该数据为空……MutableLiveData
应该总是可空的吗?
解决方案
LiveData
确实是要观察的——当你调用observe
它并传递一个处理函数时,只有当 LiveData 有一个值(当前值或新值)时才会调用该函数。因为您的 LiveData 拥有非 nullMyObject
类型,所以观察者函数只会被赋予非 null MyObject
s。
但如果你在戳它的value
属性——那就不一样了!即使您MyObject
在其构造函数中提供了初始值,您也不必这样做 - 所以LiveData
s 有时可以为空。如果您尝试观察它,则在设置值之前不会调用观察者。如果您尝试查看它value
,它将是null
,因为 LiveData 中还没有任何内容。这并不意味着它向观察者提供空值,只是它还没有存储值!
所以value
总是可以为空的,即使LiveData
持有的类型是非空的。你有点在幕后偷看。你真的有两个选择:
- 以通常的方式()使用空安全的东西
value?.let { ... }
,不要担心,因为你知道那里总会有一个值,因为你已经在构造函数中设置了一个(这是最安全的选项) - 使用
!!
,因为这似乎是少数安全的情况之一 - 你知道它不会为空
我个人认为整件事有点乱,LiveData
有……怪癖,但在这种情况下你没问题 - 我只是想解释一下发生了什么!
此外,您的公共类型应该是LiveData<MyObject>
而不是MutableLiveData<MyObject>
- 您的内部副本需要是可变的(以便您可以更新它),但您公开的引用应该是不可变LiveData
类型,因此用户无法设置它并且必须通过您的 setter 函数. 只需更改类型:
val myObject: LiveData<MyObject>
get() = myLiveData
他们会把它看作是LiveData
他们不能乱用的标准,而不是可变的子类
推荐阅读
- docker - Docker 环境变量可以用作动态入口点运行时参数吗?
- python - 无法在本地 IIS 中发布/部署 Django/Python 站点(通过 Visual Studio 发布)
- amazon-ec2 - http://169.254.169.254/latest/meta-data/instance-id 究竟提供了什么?
- react-native - 世博会不出版
- reactjs - 如何解决这个错误,下一个 js + firebase + Zeit
- spring - 如何使用 CreateDatabaseIfNotExist 从 spring 中创建具有 utf8mb4 字符集的数据库?
- c++11 - 从可变参数类模板为每种类型生成一个方法
- node.js - 构建Dockerfile Nodejs时如何连接minio
- javascript - 更新现有的 json 对象
- google-cloud-platform - 为什么我可以在 Google Cloud Platform 中看到不是我创建的项目?