gpt4 book ai didi

android - Kotlin 惰性属性和值重置 : a resettable lazy delegate

转载 作者:IT老高 更新时间:2023-10-28 13:28:48 24 4
gpt4 key购买 nike

所以我使用 kotlin for android,并且在膨胀 View 时,我倾向于执行以下操作:

private val recyclerView by lazy { find<RecyclerView>(R.id.recyclerView) }

这种方法会奏效。但是,在某些情况下,它会导致应用程序出错。如果这是一个fragment,并且fragment进入backstack,onCreateView会被再次调用,并且fragment的 View 层次将被重新创建。这意味着,惰性启动的 recyclerView 将指出一个不再存在的旧 View 。

解决办法是这样的:

private lateinit var recyclerView: RecyclerView

并初始化onCreateView里面的所有属性。

我的问题是,有没有办法重置惰性属性,以便它们可以再次初始化?我喜欢初始化都在类的顶部完成的事实,这有助于保持代码的组织性。具体问题在这个问题中找到:kotlin android fragment empty recycler view after back

最佳答案

这是一个可重置懒惰的快速版本,它可能更优雅并且需要仔细检查线程安全,但这基本上是这个想法。您需要一些东西来管理(跟踪)惰性代表,以便您可以调用重置,然后是可以管理和重置的东西。这将 lazy() 包装在这些管理类中。

以下是您的 final类的样子,例如:

class Something {
val lazyMgr = resettableManager()
val prop1: String by resettableLazy(lazyMgr) { ... }
val prop2: String by resettableLazy(lazyMgr) { ... }
val prop3: String by resettableLazy(lazyMgr) { ... }
}

然后让懒惰的人在下次访问时都回到新值:

lazyMgr.reset() // prop1, prop2, and prop3 all will do new lazy values on next access

resettablelazy的实现:

class ResettableLazyManager {
// we synchronize to make sure the timing of a reset() call and new inits do not collide
val managedDelegates = LinkedList<Resettable>()

fun register(managed: Resettable) {
synchronized (managedDelegates) {
managedDelegates.add(managed)
}
}

fun reset() {
synchronized (managedDelegates) {
managedDelegates.forEach { it.reset() }
managedDelegates.clear()
}
}
}

interface Resettable {
fun reset()
}

class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: ()->PROPTYPE): Resettable {
@Volatile var lazyHolder = makeInitBlock()

operator fun getValue(thisRef: Any?, property: KProperty<*>): PROPTYPE {
return lazyHolder.value
}

override fun reset() {
lazyHolder = makeInitBlock()
}

fun makeInitBlock(): Lazy<PROPTYPE> {
return lazy {
manager.register(this)
init()
}
}
}

fun <PROPTYPE> resettableLazy(manager: ResettableLazyManager, init: ()->PROPTYPE): ResettableLazy<PROPTYPE> {
return ResettableLazy(manager, init)
}

fun resettableManager(): ResettableLazyManager = ResettableLazyManager()

还有一些单元测试可以确定:

class Tester {
@Test fun testResetableLazy() {
class Something {
var seed = 1
val lazyMgr = resettableManager()
val x: String by resettableLazy(lazyMgr) { "x ${seed}" }
val y: String by resettableLazy(lazyMgr) { "y ${seed}" }
val z: String by resettableLazy(lazyMgr) { "z $x $y"}
}

val s = Something()
val x1 = s.x
val y1 = s.y
val z1 = s.z

assertEquals(x1, s.x)
assertEquals(y1, s.y)
assertEquals(z1, s.z)

s.seed++ // without reset nothing should change

assertTrue(x1 === s.x)
assertTrue(y1 === s.y)
assertTrue(z1 === s.z)

s.lazyMgr.reset()

s.seed++ // because of reset the values should change

val x2 = s.x
val y2 = s.y
val z2 = s.z

assertEquals(x2, s.x)
assertEquals(y2, s.y)
assertEquals(z2, s.z)

assertNotEquals(x1, x2)
assertNotEquals(y1, y2)
assertNotEquals(z1, z2)

s.seed++ // but without reset, nothing should change

assertTrue(x2 === s.x)
assertTrue(y2 === s.y)
assertTrue(z2 === s.z)
}
}

关于android - Kotlin 惰性属性和值重置 : a resettable lazy delegate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35752575/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com