我有一个 SpriteKit 项目,在真实设备上测试时,我突然看到以下错误重复打印到日志中:
由于执行期间出现错误,命令缓冲区的执行被中止。权限不足(从后台提交 GPU 工作)
当应用程序处于后台状态时,会发生这种情况。
现在,发生的事情非常明显:
SpriteKit
使用Metal
,后者在应用程序处于后台时向 GPU 提交新工作(这是您无法执行的操作)。
我通过not加载我的SpriteKit场景证实了这个理论。如果我不加载场景,则不会出现该问题。
我尝试过的:
在我的
SceneDelegate
的 sceneWillResignActive(_:)
函数中,我尝试将 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的
文档,当应用程序从/转到后台时,SpriteKit确实会自动暂停/恢复:
当应用程序从活动状态转变为非活动状态时,isPaused 会自动设置为 true。当应用程序返回到活动状态时,isPaused 会自动设置为其之前的值。Apple 表示问题与
playSoundFileNamed
的使用有关,这在某种程度上使我的
update(_:)
函数在应用程序处于后台时(以及 SpriteKit 场景暂停时!)被调用。对我来说真正奇怪的是我没有看到其他人报告这个问题。如果触发此问题只需使用 playSoundFileNamed
,我预计很多 SpriteKit 开发人员都会遇到同样的问题。也许SpriteKit用得不多?我不知道。
我看到了这个错误并且能够一致地重现它。在我的情况下,它与 playSoundFileNamed() 无关。
根据我的观察,当 SpriteKit 应用程序在无线连接到 Xcode 的设备上运行时,会出现此错误。
当应用程序在设备上关闭而某些动画仍处于活动状态(例如涉及运动中的物理主体的动画)时,该问题就会出现。发生这种情况时,Xcode 无法正常停止执行,导致重复出现上述错误消息。这个循环一直持续到通过 Xcode 停止正在运行的应用程序为止。