2015-06-20 78 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()從場景中刪除精靈(與發射器作爲一個孩子),這將調用重寫的方法並從精靈中移除煙霧發射器,然後從場景中移除精靈。