命令缓冲区的执行由于执行期间的错误而中止。权限不足(从后台提交 GPU 工作)

Execution of the command buffer was aborted due to an error during execution. Insufficient Permission (to submit GPU work from background)

我有一个 SpriteKit 项目,在真实设备上测试时,我突然看到以下错误重复打印到日志中:

Execution of the command buffer was aborted due to an error during execution. Insufficient Permission (to submit GPU work from background)

当应用程序处于后台状态时会发生这种情况。

现在,很明显发生了什么:SpriteKit 使用 Metal,后者在应用程序后台运行时向 GPU 提交新工作(这是你不能做的事情).

我已经通过 加载我的 SpriteKit 场景证实了这个理论。如果我不加载场景,就不会出现这个问题。

我试过的:

在我的 SceneDelegatesceneWillResignActive(_:) 函数中,我尝试将 isPaused 设置为 true,如下所示:

func sceneWillResignActive(_ scene: UIScene) {
    GameSceneHelper.scene.isPaused = true
    CloudSceneHelper.scene.isPaused = true
}

...然后继续sceneDidBecomeActive(_:)中的场景,像这样:

func sceneDidBecomeActive(_ scene: UIScene) {
    GameSceneHelper.scene.isPaused = false
    CloudSceneHelper.scene.isPaused = false
}

我认为这行得通,但行不通。错误仍然存​​在。

问题:

这是怎么回事?为什么我突然收到这个新错误,我该如何解决这个问题?

谢谢!

编辑:

我找到了一个(丑陋的)解决方法:因为我的 SpriteKit 场景是使用 SwiftUI 呈现的,所以我可以设置一个布尔值来指示是否显示场景。我这样做没有报错。

不幸的是,这会导致不良行为:1) 当您将应用滑开时,您会看到场景突然消失,2) 当您将应用移至前台时,您会看到场景突然重新出现,以及 3 ) 应用程序快照(iOS 在您将应用程序移至后台时拍摄的应用程序快照)显示空白屏幕,因为在拍摄快照时场景已经隐藏。

一开始我不明白为什么会这样;我的理解是,当应用程序处于后台时,SpriteKit 场景会自动暂停。

所以,我仍在寻找更好的解决方案 -- 也许还有一个解释。

编辑#2:

根据 Apple 的 documentation,当应用进入 from/to 背景时,SpriteKit 确实会自动 paused/resumed:

When an application moves from an active to an inactive state, isPaused is automatically set to true. When an application returns to an active state, isPaused is automatically set to its previous value.

我在向 Apple 支持发送了一个说明该问题的 Xcode 项目后收到了回复。他们建议我使用反馈助手提交错误报告。所以,这似乎是一个合法的错误。

A​​pple 表示问题与 playSoundFileNamed 的使用有关,这不知何故使得我的 update(_:) 函数在应用程序处于后台时(以及 SpriteKit 场景暂停时)被调用!).

对我来说真正奇怪的是我没有看到其他人报告这个问题。如果只需要使用 playSoundFileNamed 就可以触发它,我希望很多 SpriteKit 开发人员都会遇到同样的问题。也许 SpriteKit 没有那么常用?我不知道。