@TryLoveCatch
2024-09-06T08:37:39.000000Z
字数 2264
阅读 59
Kotlin知识体系
private fun updateState(expectedState: Any?, newState: Any): Boolean {
var curSequence = 0
var curSlots: Array<StateFlowSlot?>? = this.slots // benign race, we will not use it
synchronized(this) {
val oldState = _state.value
if (expectedState != null && oldState != expectedState) return false // CAS support
if (oldState == newState) return true // Don't do anything if value is not changing, but CAS -> true
_state.value = newState
curSequence = sequence
if (curSequence and 1 == 0) { // even sequence means quiescent state flow (no ongoing update)
curSequence++ // make it odd
sequence = curSequence
} else {
// update is already in process, notify it, and return
sequence = curSequence + 2 // change sequence to notify, keep it odd
return true // updated
}
curSlots = slots // read current reference to collectors under lock
}
/*
Fire value updates outside of the lock to avoid deadlocks with unconfined coroutines.
Loop until we're done firing all the changes. This is a sort of simple flat combining that
ensures sequential firing of concurrent updates and avoids the storm of collector resumes
when updates happen concurrently from many threads.
*/
while (true) {
// Benign race on element read from array
curSlots?.forEach {
it?.makePending()
}
// check if the value was updated again while we were updating the old one
synchronized(this) {
if (sequence == curSequence) { // nothing changed, we are done
sequence = curSequence + 1 // make sequence even again
return true // done, updated
}
// reread everything for the next loop under the lock
curSequence = sequence
curSlots = slots
}
}
}
重点是这句if (oldState == newState) return true
,所以是通过==
来进行比较的
== 操作符
- 结构相等(内容相等)的比较,等同于调用 equals() 方法。
- 它用于比较两个对象的内容是否相等。
- 即使两个对象的内存地址不同,只要它们的内容相等,== 仍然会返回 true
=== 操作符
- 引用相等的比较,用来检查两个对象是否是同一个引用。
- 它比较的是两个对象在内存中的地址是否相同。
- 只有当两个变量引用的是同一个对象实例时,=== 才会返回 true。
所以我们可以理解为,当你在 Kotlin 中使用 == 时,编译器会将它转换为对 equals() 方法的调用。
一般来说,StateFlow我们会使用data class
,在 Kotlin 中,数据类(data class)会自动为你生成 equals() 方法,它会根据所有的属性值来比较对象是否相同,默认的 equals()大致是如下这样实现的:
class Person(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true // 引用相等
if (other !is Person) return false // 类型检查
// 比较内容相等
return name == other.name && age == other.age
}
override fun hashCode(): Int {
return name.hashCode() * 31 + age
}
}
所以我们现在可以总结出来StateFlow的默认比较策略:
==
比较内容 ==
来比较所以针对这个策略,我们想要保证StateFlow更新,就需要如下对策:
===
,不要比较地址