SCNSceneRenderer委托数据竞态警告问题及修复咨询
问题分析与修复方案
为什么会出现这个数据竞态警告?
- 你的
ViewModel标记了@MainActor,这意味着编译器会强制所有实例方法在主线程执行。但SCNSceneRendererDelegate的renderer(_:updateAtTime:)方法是由系统在**渲染线程(非主线程)**调用的,直接违反了@MainActor的线程约束,所以最初的代码会触发警告。 - 你修改后用
MainActor.run确保了属性更新在主线程,但方法本身的调用依然在非主线程。由于ViewModel的@MainActor约束覆盖所有实例方法,编译器仍会针对方法定义行发出警告,提示该方法未在主线程执行。
修复方法
给renderer(_:updateAtTime:)方法添加@MainActor(unsafe)修饰符,明确告诉编译器这个方法可以在非主线程执行,同时在方法内部保证属性修改在主线程:
@MainActor @Observable final class ViewModel: NSObject, @preconcurrency SCNSceneRendererDelegate { private(set) weak var renderer: (any SCNSceneRenderer)? //… @MainActor(unsafe) func renderer(_ renderer: any SCNSceneRenderer, updateAtTime time: TimeInterval) { Task { @MainActor in self.renderer = renderer } } }
@MainActor(unsafe)的作用是临时豁免该方法的@MainActor线程约束,允许它在非主线程被调用;而Task { @MainActor in }则确保对renderer属性的修改严格在主线程执行,彻底解决数据竞态问题。
内容的提问来源于stack exchange,提问作者Reinhard Männer
相关产品推荐
相关产品推荐

