Compose Multiplatform中ComposeUIViewController回调被调用两次的原因?
Compose Multiplatform iOS端ComposeUIViewController回调重复执行问题
我通过Compose Multiplatform Wizard创建跨平台项目后,在iOS模拟器运行时发现ComposeUIViewController的lambda回调被调用了两次,但外层的MainViewController函数仅执行一次。
代码示例
composeApp/src/iosMain/kotlin/main.kt中的代码如下:
fun MainViewController(systemAppearance: (isLight: Boolean) -> Unit): UIViewController { println("Outside ComposeUIViewController") return ComposeUIViewController { println("Inside ComposeUIViewController") App() } }
控制台输出
运行后的输出截图:
问题原因
这种现象是Compose Multiplatform在iOS端的正常行为:ComposeUIViewController的content lambda作为Compose的重组入口,会在视图首次初始化和**系统外观切换(亮/暗色模式)**时触发执行,或是因视图生命周期的状态变化引发重组,导致回调重复执行。而MainViewController仅在UIViewController实例创建时调用一次,所以外层打印只出现一次。
解决方案
方案1:用LaunchedEffect包裹单次执行逻辑
借助Compose的LaunchedEffect(Unit)确保初始化逻辑仅在Compose首次启动时运行:
fun MainViewController(systemAppearance: (isLight: Boolean) -> Unit): UIViewController { println("Outside ComposeUIViewController") return ComposeUIViewController { LaunchedEffect(Unit) { println("仅执行一次的初始化逻辑") } println("UI构建代码(每次重组都会执行)") App() } }
方案2:用状态标记控制执行次数
通过remember保存状态标记,避免重复执行初始化逻辑:
fun MainViewController(systemAppearance: (isLight: Boolean) -> Unit): UIViewController { println("Outside ComposeUIViewController") return ComposeUIViewController { val hasInitialized = remember { mutableStateOf(false) } if (!hasInitialized.value) { println("Inside ComposeUIViewController - 仅执行一次") hasInitialized.value = true } App() } }
方案3:将单次逻辑移至MainViewController函数内
如果是不需要依赖Compose环境的初始化逻辑,直接放在MainViewController函数中即可(该函数仅执行一次):
fun MainViewController(systemAppearance: (isLight: Boolean) -> Unit): UIViewController { println("Outside ComposeUIViewController") // 这里放置仅需执行一次的初始化逻辑 println("单次初始化逻辑") return ComposeUIViewController { println("UI构建代码") App() } }
内容的提问来源于stack exchange,提问作者Shoaib Kakal
相关产品推荐
相关产品推荐

