SwiftUI中能否同时为类使用@MainActor与EnvironmentKey?
可以同时使用@MainActor和EnvironmentKey,只需调整初始化方式
你遇到的错误核心原因是:@MainActor修饰ViewModel后,类的所有成员(包括默认生成的init())都会被标记为主协程隔离,而EnvironmentKey的static defaultValue是在非隔离的同步上下文里初始化的,直接调用隔离的初始化方法就会触发报错。
具体解决方法
修改HomeViewModelKey的defaultValue,通过Task同步等待主协程内的初始化操作,既满足ViewModel的隔离要求,又符合EnvironmentKey对同步值的需求:
struct HomeViewModelKey: EnvironmentKey { static var defaultValue: HomeView.ViewModel { Task { @MainActor in HomeView.ViewModel() }.value } } extension EnvironmentValues { var homeViewModel: HomeView.ViewModel { get { self[HomeViewModelKey.self] } set { self[HomeViewModelKey.self] = newValue } } }
原理说明
Task { @MainActor in ... }强制在主协程中执行ViewModel的初始化,完全符合@MainActor的隔离规则Task.value会同步等待任务执行完成,返回初始化后的实例,满足EnvironmentKey对defaultValue的同步获取要求
这样调整后,既能保留ViewModel的@MainActor修饰(确保@Published属性在主协程更新,避免UI线程异常),也能正常实现EnvironmentKey的环境变量注入功能。
内容的提问来源于stack exchange,提问作者Ammar Ahmad
相关产品推荐
相关产品推荐

