我有一个ViewModel类,看起来像这样:

class EditUserViewModel(
    private val initUser: User,
) : ViewModel() {

    private val _user = MutableLiveData(initUser)
    val user: LiveData<User>
        get() = _user

    fun hasUserChanged() = initUser != _user.value

}
User可以通过UI更新User数据类实例的某些属性。
要检查从片段导航时是否有任何更改,我使用了hasUserChanged方法。
问题是,这总是错误的。我检查了一下,似乎每次更改_user initialUserMutableLiveData都会更改。
这是为什么? MutableLiveData的初始值是否通过引用传递?我一直认为Kotlin是一种“按值(value)传递”的语言。
更新:
复制initUser并将其放入MutableLiveData之前,该问题似乎消失了。
private val _user = MutableLiveData(initUser.copy())
但是对我来说仍然没有意义,为什么我必须这样做。

最佳答案

Kotlin就像Java,它们都是按值传递的。如果在equals类中实现User函数,或者将其设置为data class(隐式实现equals函数),则可以确保!=运算符检查用户对象的内容。
更新
如果直接更改LiveData的值,例如这样的话:

_user.value.name = "some name"
这意味着您正在更改nameinitUser属性,因为_user.value完全引用了initUser所做的对象。因此,!=运算符始终返回false,因为我们有一个对象有两个引用。
现在,当您这样做时:
private val _user = MutableLiveData(initUser.copy())
您正在创建initUser的深拷贝(我们将其称为X),这是内存中具有initUser相同属性值的新对象。
因此,通过更改其属性,例如:_user.value.name = "some name",实际上,您是在X而不是initUser上进行此更改。这导致将初始值保留在initUser中,这意味着不要更改它们,并解决问题。

关于android - LiveData “pass-by-reference”初始值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63795289/

10-12 00:29