GyroUpdate和重启场景在枚举崩溃时发生突变(SpriteKit和Swift)



我有一个 Swift SpriteKit 场景,它不会每次都发生,但我通过按菜单对重新启动游戏按钮进行了一些测试,并反复快速连续重新启动,直到它崩溃。它还从加载场景的其他点随机崩溃。我的估计是,它有大约30%的可能性在这条线上崩溃。

class AppDelegate: UIResponder, UIApplicationDelegate {

并显示以下错误:

2015-03-07 09:52:14.347 DDgame[1457:433285] * 终止应用程序到期 对于未捕获的异常"NSGenericException",原因:"* 集合 <__NSArrayM:0x170051e50>在被列举时发生了变异。 第一个抛出调用堆栈:(0x18342259c 0x193b6c0e4 0x183421f50 0x187a57538 0x187a56c84 0x187a5661c 0x187a56510 0x10008f4c0 0x1000913b0 0x187a46bcc 0x187a43fd8 0x187a41038 0x187a6dfd8 0x100360a9c 0x187575280 0x187575118 0x1845718d0 0x1833c55e4 0x1833da200 0x1833da160 0x1833d80e0 0x1833050a4 0x18c49f5a4 0x187c36aa4 0x1000d1204 0x1000d1244 0x1941daa08) libc++abi.dylib: 终止与类型为 NSException (lldb) 的未捕获异常

我使用了一个捕获所有异常断点,发现它在陀螺仪更新的更新方法中崩溃。有没有人有更安全的方法可以通过更新按钮保持陀螺仪的安全运行?

这是touchesBegind方法的摘录,我已经删除了位于其他按钮中的代码,只是为了不在这里产生太多绒毛:(不确定你们是否需要这里的附加功能?

            else if node.name == "replayButton" {
                    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
                        NSNotificationCenter.defaultCenter().removeObserver(self, name: "pauseGame", object: nil)

                        let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
                        scene.scaleMode = SKSceneScaleMode.AspectFill
                        self.view?.presentScene(scene, transition: transition)
            }

我发现它在更新方法中的陀螺仪更新上崩溃:

override func update(currentTime: NSTimeInterval) {
    var timeSinceLast = currentTime - lastUpdateTimeInterval
    lastUpdateTimeInterval = currentTime
    if(!gameOver) {
        //check for gameover
        if (self.goldStash <= 0) {   
            gameOver = true
            gameIsPaused = true
            self.gameOverMethod()
        }

        //spawning logic
        spawnEngine()
        //gyro update
        if (self.motionManager.gyroData != nil) {
            self.updateGyroNodeWithData(self.childNodeWithName("GoldBack") as? SKSpriteNode, gyroIn: motionManager.gyroData)
            self.updateGyroNodeWithDataReverse(self.childNodeWithName("GoldFront") as? SKSpriteNode, gyroIn: motionManager.gyroData)
            self.updateGyroNode(self.childNodeWithName("CBack1") as? SKSpriteNode, gyroIn: motionManager.gyroData, minIn: cBack1position.x-10.0, maxIn: cBack1position.x+10.0, sensitivity: 0.8)
            self.updateGyroNode(self.childNodeWithName("CBack2") as? SKSpriteNode, gyroIn: motionManager.gyroData, minIn: cBack2position.x-10.0, maxIn: cBack2position.x+10.0, sensitivity: 0.8)
            self.updateGyroNode(self.childNodeWithName("CBack3") as? SKSpriteNode, gyroIn: motionManager.gyroData, minIn: cBack3position.x-10.0, maxIn: cBack3position.x+10.0, sensitivity: 0.8)
            self.updateGyroNode(self.childNodeWithName("CBack4") as? SKSpriteNode, gyroIn: motionManager.gyroData, minIn: cBack4position.x-10.0, maxIn: cBack4position.x+10.0, sensitivity: 0.8)
        } 
    }
    if timeSinceLast > 1 {
        timeSinceLast = kMinTimeInterval
    }
    updateWithTimeSinceLastUpdate(timeSinceLast)
}
func updateWithTimeSinceLastUpdate(timeSinceLast: NSTimeInterval) {
    for dwarf in dwarves {
        dwarf.updateWithTimeSinceLastUpdate(timeSinceLast)
    }
}

我解决了这个问题。正是在这段代码中:

self.childNodeWithName("GoldBack") as? SKSpriteNode

它不断枚举节点的场景,而场景随后被销毁。我尝试输入一个布尔值以防止陀螺仪更新在菜单打开时运行,但由于某种原因它不断崩溃,百分比显着下降,但有些东西不起作用。

最好的解决方案是在 init 中创建节点的变量,然后在更新方法中对节点运行陀螺仪更新。

var goldBack = SKSpriteNode?()
goldBack = self.childNodeWithName("GoldBack") as? SKSpriteNode

然后在更新方法中:

self.updateGyroNodeWithData(goldBack, gyroIn: motionManager.gyroData)

以前不知道这一点,但是,真正帮助我的另一件事是在Xcode中添加了"所有异常"断点。(这是通过转到断点导航器,按左下角的 + 并添加异常断点来完成的)

最新更新