1 lambda android closures memory-leaks kotlin
我有一个关于 kotlin lambda 和对this. 让我们看一下这段代码:
class MyViewModel: ViewModel {
val eventFlow = mutableSharedFlow<Unit>()
}
class MyFragment: Fragment() {
val viewModel = MyViewModel()
val lambda_1: (Unit) -> Unit = { Log.v("TAG", "Event happened") }
val lambda_2: (Unit) -> Unit = { processEvent() }
fun processEvent() {
//do smth
}
override fun onCreate(bundle: Bundle?) {
lifecycleScope.launchWhenStarted {
viewModel.eventFlow.collect(lambda_1)
}
lifecycleScope.launchWhenStarted {
viewModel.eventFlow.collect(lambda_2)
}
}
}
Run Code Online (Sandbox Code Playgroud)
请告诉我我的说法是否正确:
lambda_1不调用 的任何方法或变量MyFragment,因此它不保存对MyFragment对象的引用。lambda_2确实从 调用方法MyFragment,因此它确实持有对对象的引用MyFrgament。viewModel-> eventFlow-> lambda_2-> MyFragment。尝试读取字节码但无法从中找出答案。
1. 是的,这是正确的。lambda_1不需要对 的引用MyFragment,因此它不会保留一个。事实上,由于 可能lambda_1是完全静态的,Kotlin 编译器会创建一个单例并为 的所有实例重用同一个实例MyFragment。
2.这也是正确的。lambda_2需要引用MyFragment,因此它保留了一个。在这种特定情况下,它的工作方式与内部类类似,因此当MyFragment实例化 lambda 时,它会通过构造函数传递对其自身的引用。一般来说,它是不同的,因为 lambda 保存对其需要的任何对象的引用,无论它是否是“外部”类。
3. 说实话,我对 MVVM 不是很熟悉,但我认为它的限制与一般的良好实践相同。
A)。如果您关注的是应用程序架构和关注点分离,因此较低层不应调用较高层,那么这种情况并不违反此规则。View只在viewmodel中注册一个事件,但viewmodel仍然不直接引用view,也不知道它们。
b). 如果您担心 的实例MyFragment被泄漏,它无法被垃圾收集,那么在这种特定情况下这不是问题。收集流量时MyFragment使用。lifecycleScope当片段被销毁时,它会lifecycleScope取消所有启动的协程,流收集器也会被取消,因此不再需要 lambda 并且可以进行垃圾收集。
| 归档时间: |
|
| 查看次数: |
327 次 |
| 最近记录: |