提问人:baltekg 提问时间:9/8/2020 最后编辑:baltekg 更新时间:9/8/2020 访问量:1091
LiveData“按引用传递”初始值
LiveData "pass-by-reference" initial value
问:
我有一个看起来像这样的类: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 数据类实例的某些属性。
为了检查从片段导航时是否有任何变化,我使用方法。
问题是这总是错误的。我检查了一下,似乎每次我更改_user时都会发生变化.
为什么?的初始值是通过引用传递的吗?我一直认为 Kotlin 是一种“按值传递”类型的语言。hasUserChanged
initialUser
MutableLiveData
MutableLiveData
更新:
在将其放入 .initUser
MutableLiveData
private val _user = MutableLiveData(initUser.copy())
但对我来说,为什么我必须这样做仍然没有意义。
答:
1赞
aminography
9/8/2020
#1
Kotlin 就像 java,它们是按值传递的。如果在类中实现函数,或将其设为 (隐式实现函数),则可以确保运算符检查用户对象的内容。equals
User
data class
equals
!=
更新
如果要直接更改 的值,例如:LiveData
_user.value.name = "some name"
这意味着您正在更改 的属性,因为 恰好指的是 所做的对象。因此,运算符总是返回 false,因为我们有一个对象有两个对它的引用。name
initUser
_user.value
initUser
!=
现在,当您这样做时:
private val _user = MutableLiveData(initUser.copy())
您正在创建 (我们称之为 ) 的深层副本,它是内存中具有相同属性值的新对象。initUser
X
initUser
因此,通过更改其属性,例如:,实际上,您是在 上进行此更改,而不是 。它导致保留 中的初始值,这意味着不要更改它们,并解决问题。_user.value.name = "some name"
X
initUser
initUser
评论
0赞
baltekg
9/8/2020
该类确实是 so 方法正确地比较它们。但问题是这两个比较的值是相同的 - 每次更新值时都会更新。User
data class
hasUserChanged
initUser
_recipe
0赞
aminography
9/8/2020
好的,所以如果它是一个数据类,它不介意检查具有相同内容的两个对象的相等性或检查对象本身。我想问题出在别的地方。请像以下方式进行更改,然后检查 logcat 输出:!=
hasUserChanged
fun hasUserChanged(): Boolean { println("initUser: ${initUser.toString()}") println("_user.value: ${_user.value.toString()}") return initUser != _user.value }
0赞
baltekg
9/8/2020
我完全按照你说的做了,这两个对象是一样的,每个值都是一样的。我还使用 xml 文件中的“viewModel.recipe”来更新 UI。但我不知道这是否是我问题的原因。data binding
评论