LiveData“按引用传递”初始值

问题描述

我有一个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 initialUser时,mutablelivedata都会更改。
这是为什么? mutablelivedata的初始值是否通过引用传递?我一直以为Kotlin是一种“按价值传递”的语言。

更新: 在将initUser放入mutablelivedata之前复制private val _user = mutablelivedata(initUser.copy()) 时,问题似乎消失了。

@AttributeOverrides

但是我仍然没有理由为什么要这样做。

解决方法

Kotlin类似于Java,它们是按值传递的。如果您在equals类中实现User函数,或者将其设置为data class(隐式实现equals函数),则可以确保用户的内容对象由!=运算符检查。

更新

例如,直接更改LiveData的值,例如:

_user.value.name = "some name"

这意味着您正在更改name的{​​{1}}属性,因为initUser完全引用_user.value所做的对象。因此,initUser运算符始终返回false,因为我们有一个对象有两个引用。

现在,当您这样做时:

!=

您正在创建private val _user = MutableLiveData(initUser.copy()) 的深层副本(我们将其称为initUser),它是内存中具有X相同属性值的新对象。

因此,实际上,通过更改initUser之类的属性,您是在_user.value.name = "some name"而非X上进行了此更改。这导致保留initUser中的初始值,这意味着不要更改它们并解决问题。