Kotlin Lambda是否持有创建对象引用?及MVVM规范相关疑问
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) } } }
三个说法的判断与分析
说法1正确
lambda_1内部仅调用全局的Log.v方法,未访问MyFragment的任何成员变量或方法,也没有隐式引用this。Kotlin会将这类不捕获外部类成员的lambda编译为静态函数对象,不会持有MyFragment的实例引用。说法2正确
lambda_2里的processEvent()等价于this.processEvent(),这里的this指向MyFragment实例。Kotlin会让该lambda捕获外部类的this引用,因此lambda_2会持有MyFragment对象的引用。说法3正确
调用viewModel.eventFlow.collect(lambda_2)时,collect方法会持有传入的lambda作为下游收集器,而eventFlow属于MyViewModel实例,由此形成引用链:MyViewModel→eventFlow→lambda_2→MyFragment。这确实违反了MVVM中「ViewModel不得持有View层引用」的原则,可能引发内存泄漏——比如Fragment销毁后,存活的ViewModel会通过这条引用链阻止Fragment被GC回收。
内容的提问来源于stack exchange,提问作者pti4ik
相关产品推荐
相关产品推荐

