提问人:progquester 提问时间:7/13/2023 最后编辑:progquester 更新时间:7/18/2023 访问量:180
SnapshotStateList 如何检测已发生更改?
How SnapshotStateList detects that a change has occurred?
问:
假设我有一个 Student 的 SnapshotStateList,并且 Student 的定义是:
data class Student<val id: Int, var name: String>
val students = mutableStateListOf(Student(0, "Aaron"))
我的 Jetpack 作曲想要在学生更改时重新作曲。
找到以下函数来触发它:
fun addStudent(name: String) {
students.add(Student(students.size, "Bob"))
}
fun removeStudent(key: Int) {
students.remove(key)
}
fun replaceStudent(key: Int, name: String) {
val old = students[key]
students[key] = Student(old.key, name)
}
但以下函数无法触发它:
fun modifyStudent(key: Int, name: String) {
students[key].name = name
}
为什么,SnapshotStateList 如何检测发生了更改?
答:
1赞
chuckj
7/18/2023
#1
快照系统将检测自身的变化,而不是其中可变状态的变化。SnapshotStateList
代码,
fun replaceStudent(key: Int, name: String) {
val old = students[key]
students[key] = Student(old.key, name)
}
修改并被检测为更改。students
fun modifyStudent(key: Int, name: String) {
students[key].name = name
}
修改快照系统未将其视为更改的某些对象的属性。name
Student
我建议你让 immutable 而不是 mutable,Student
data class Student(val id: Int, val name: String)
然后需要修改更新学生。replaceStudent
或者,您可以更改为Student
class Student(val id: Int, name: String) {
var name by mutableStateOf(name);
}
这将使可观察性并在属性更改时通知 Compose。Student
name
我建议将 immutable 设为不可变。Student
作为奖励,我建议你在这种情况下使用而不是,就好像你曾经在删除后调用学生上方的索引将不匹配到 .使用 a 将解决此问题。您还需要将 更改为不用作下一个,而是使用全局整数或全局原子(如果您是多线程的),因为现在,创建新学生将覆盖现有学生的数据,因为如果删除了任何学生,则会导致生成重复值。SnapshotStateMap
SnapshotStateList
removeStudent
key
students
SnapshotStateMap
addStudent
size
id
key
评论
0赞
progquester
7/18/2023
谢谢。该代码仅用于描述我的问题,实际上不会在产品中使用。我实际上试图弄清楚的是,在内部,SnapshotStateList 如何检查它是否已更改并像可写一样调用回调。
0赞
chuckj
7/21/2023
快照系统采用多版本并发控制算法,在修改数据之前,使用写入时复制的方式生成数据的快照本地可变副本。SnapshotStateList 在内部使用不可变数组,该数组使用允许副本增量的持久性数据结构。换句话说,它不会检测到更改。更改状态对象时,将生成副本。快照维护一组已复制的对象,并通知组合有关此集合的信息,并将重新组合读取集合中任何对象的任何函数。
评论