LiveData "pass-by-reference" 初始值
LiveData "pass-by-reference" initial value
我有一个 ViewModel
class 看起来像这样:
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.
更新用户数据class实例的一些属性
要检查从片段导航时是否有任何更改,我使用 hasUserChanged
方法。
问题是它总是错误的。我检查了一下,似乎每次更改 _user MutableLiveData
.
时 initialUser
都会更改
这是为什么? MutableLiveData
的初始值是通过引用传递的吗?我一直认为Kotlin是一种“传值”类型的语言。
更新:
在将 initUser
放入 MutableLiveData
.
之前复制 initUser
时,问题似乎消失了
private val _user = MutableLiveData(initUser.copy())
但我仍然不明白为什么我必须这样做。
Kotlin 就像 java 而它们是 pass-by-value。如果您在 User
class 中实现 equals
函数,或者将其设置为 data class
(隐式实现 equals
函数),则可以确保用户对象的内容由 !=
运算符检查。
更新
如果您直接更改 LiveData
的值,例如这样:
_user.value.name = "some name"
这意味着你正在改变initUser
的name
属性,因为_user.value
恰好是指initUser
所做的对象。因此,!=
运算符总是 returns 假,因为我们有一个对象有两个对它的引用。
现在,当您这样做时:
private val _user = MutableLiveData(initUser.copy())
您正在创建 initUser
的深层副本(我们称之为 X
),它是内存中的新对象,具有与 initUser
相同的 属性 值。
因此,通过更改其属性,例如:_user.value.name = "some name"
,实际上,您是在 X
而不是 initUser
上进行此更改。它导致保留 initUser
中的初始值,意思是不要更改它们,并解决问题。
我有一个 ViewModel
class 看起来像这样:
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.
更新用户数据class实例的一些属性
要检查从片段导航时是否有任何更改,我使用 hasUserChanged
方法。
问题是它总是错误的。我检查了一下,似乎每次更改 _user MutableLiveData
.
时 initialUser
都会更改
这是为什么? MutableLiveData
的初始值是通过引用传递的吗?我一直认为Kotlin是一种“传值”类型的语言。
更新:
在将 initUser
放入 MutableLiveData
.
initUser
时,问题似乎消失了
private val _user = MutableLiveData(initUser.copy())
但我仍然不明白为什么我必须这样做。
Kotlin 就像 java 而它们是 pass-by-value。如果您在 User
class 中实现 equals
函数,或者将其设置为 data class
(隐式实现 equals
函数),则可以确保用户对象的内容由 !=
运算符检查。
更新
如果您直接更改 LiveData
的值,例如这样:
_user.value.name = "some name"
这意味着你正在改变initUser
的name
属性,因为_user.value
恰好是指initUser
所做的对象。因此,!=
运算符总是 returns 假,因为我们有一个对象有两个对它的引用。
现在,当您这样做时:
private val _user = MutableLiveData(initUser.copy())
您正在创建 initUser
的深层副本(我们称之为 X
),它是内存中的新对象,具有与 initUser
相同的 属性 值。
因此,通过更改其属性,例如:_user.value.name = "some name"
,实际上,您是在 X
而不是 initUser
上进行此更改。它导致保留 initUser
中的初始值,意思是不要更改它们,并解决问题。