2015-06-20 77 views
1

我创建了一个SKEmitterNode,以便在他死后将其附加到我的玩家。这是一个非常简单的烟雾。问题是,我在以下任何一种情况下崩溃了游戏:SKEmitterNode导致场景重新启动时崩溃

1)点击重试按钮并转换到同一场景,随机时,它会以EXC_BAD_ACCESS错误使游戏崩溃。

2)返回到主屏幕并在至少一次死亡并创建发射器节点后点击播放并转换到该游戏场景。

当前SKEmitterNode是一个可选的类变量。当玩家死亡时,他们设置SKEmitterNode并将其附加到场景中。

// Add death smoke 
    let smokePath: String = NSBundle.mainBundle().pathForResource("playerDeathSmoke", ofType: "sks")! 
    self.deathSmokeEmitter = NSKeyedUnarchiver.unarchiveObjectWithFile(smokePath) as? SKEmitterNode 
    self.deathSmokeEmitter?.name = "deathSmokeEmitter" 
    if let deathEmitter = self.deathSmokeEmitter { 
     deathEmitter.targetNode = self.scene 
     self.addChild(deathEmitter) 
    } 

“self.addChild(deathEmitter)” 会导致崩溃后重新加载场景(烟确实出现)。这与SKEmitterNode文档中的示例代码添加发射器节点的方式相同。

我也试过各种各样的东西来修复它,就好像覆盖Player sprite上的removeFromParent方法,并在转换场景之前对其自己运行“removeFromParent”。

override func removeFromParent() { 
     self.deathSmokeEmitter?.removeFromParent() 
     //self.deathSmokeEmitter?.targetNode = nil 

     super.removeFromParent() 
    } 

做完这个之后,只有当返回到主屏幕然后转换回游戏场景时才会发生崩溃。这意味着我可以在需要时多次快速尝试重试,但如果我回到主场景并返回到游戏场景,它仍会崩溃。此外,当它崩溃这样,堆栈跟踪显示这最后的方法崩溃之前:

[SKEffectNode dealloc] 

请让我知道如果您有任何意见和感谢! PS:我在转换过程中没有做任何奇怪的事情。我只是实例化一个转换并推动下一个场景。我依靠SpriteKit来照顾所有的清洁工作。

+0

这可能值得一看仪器中的任何内存泄漏。你得到的错误是试图访问一个不存在的变量的结果。 –

+0

有没有专门做这些的指南?我从来没有和仪器用户界面非常不直观。我找不到任何好的指导说:“这是你如何查明内存泄漏并修复它们”。 – lespommes

+0

几天前我在[raywenderlich.com](http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode)上使用了这个教程,它帮助我找到了一些泄漏我根本没有期待。这已经过了几年了,但按照你的项目的步骤应该会有所帮助。 –

回答

1

所以我发现如何解决这个问题(当我问这个问题的时候,我已经知道了)但是为了澄清我输入了它。

由于某些原因,iOS 8中的SpriteKit在切换场景时并未从播放器精灵中移除烟雾发射器。这在某种程度上导致了崩溃,因为它试图在下一个场景中出于某种原因对其进行逻辑处理。

我上面的内容几乎是正确的。首先覆盖与粒子发射器的孩子removeFromParent精灵()这样的方法

// Sprite with ParticleEmitterNode child attached to it's method 
override func removeFromParent() { 
    self.deathSmokeEmitter?.removeFromParent() 

    super.removeFromParent() 
} 

在切换场景,只是做一个spriteWithEmitterChild.removeFromParent()从场景中删除精灵(与发射器作为一个孩子),这将调用重写的方法并从精灵中移除烟雾发射器,然后从场景中移除精灵。