2015-12-02 44 views
2

我一直在嘗試修復SpriteKit中的大量內存增加現在已經很多周了,但沒有找到解決方案。我已經嘗試了幾乎所有在線管理SK內存的方法,但仍然遇到麻煩。這裏是我的情況:儘管removeAllChildren調用了存儲器增加了SpriteKit

我首先提出的SKScene「主屏幕」,並從那裏我改變頁面的場景一個UIButton在我的視圖控制器像這樣:

func nextPage(sender: UIButton) { 

    pageNumber = pageNumber + 1 

    let switchPage = SKTransition.crossFadeWithDuration(3.0) 
    switchPage.pausesOutgoingScene = false 

    switch pageNumber { 
    case 1: self.skView.presentScene(Page01(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 2: self.skView.presentScene(Page02(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 3: self.skView.presentScene(Page03(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 4: self.skView.presentScene(Page04(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 5: self.skView.presentScene(Page05(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 6: self.skView.presentScene(Page06(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 7: self.skView.presentScene(Page07(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 8: self.skView.presentScene(Page08(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 9: self.skView.presentScene(Page09(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 10: self.skView.presentScene(Page10(size: (self.view?.bounds.size)!), transition: switchPage) 
    case 11: self.skView.presentScene(Page11(size: (self.view?.bounds.size)!), transition: switchPage) 
    default: 
     break 
    } 
} 

這裏是在Xcode我的記憶中圖:

enter image description here

正如你看到的,我的主屏幕(HS)記憶開始於38.1和我已經通過所有的場景和循環回來它在112我也裝結束主屏幕上的時間每個頁面單獨並記錄下內存以確認增加。

在每個SKScene,我加載不同的對象,然後在willMoveFromView我刪除它們像這樣:

override func willMoveFromView(view: SKView) { 

    //Remove the Scroller Components 
    self.view?.removeGestureRecognizer(self.page01Drops.panGestureRecognizer) 
    self.page01Drops = nil 

    //Remove Environment 
    self.randomObjectFromScene.texture = nil 

    self.anotherRandomObject.removeFromParent 

    self.removeAllActions() 
    self.removeAllChildren() 
} 

這裏有一個小的詳細信息: - DEINIT沒有被場景變化後調用。

  • 我用儀器測試應用程序時沒有泄漏。

  • 所有SKTextures首先作爲UIImages使用stringByAppendingPathComponent加載。

  • 所有willMoveFromView方法都包含removeAllActions和removeAllChildren。

有誰知道我爲什麼記憶力在​​增加?

更新多一點的示例代碼

這是我如何加載我skView在viewDidLoad中:

skView = view as! SKView 
    skView.showsFPS = true 
    skView.showsNodeCount = true 
    skView.ignoresSiblingOrder = false 
    skView.presentScene(homeScreen(size: skView.bounds.size)) 

這裏是從我的頁01 SKScene了一下:

class Page01: SKScene { 
    //Preload Textures 
    let aaronHead01Texture = SKTexture(image: UIImage(contentsOfFile:NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent("P01_head01.png"))!) 
    let aaronHead02Texture = SKTexture(image: UIImage(contentsOfFile:NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent("P01_head02.png"))!) 
    //more textures for body parts of character that will be changed 

    var aaronHead: SKSpriteNode! 
    //More SKSpriteNodes for other body parts 

    override init(size: CGSize){ 
     super.init(size: size) 

     self.aaronHead = SKSpriteNode(texture: self.aaronHead01Texture) 
     self.aaronHead.anchorPoint = CGPoint(x: 0.5, y: 0.1) 
     self.aaronHead.position = CGPoint(x: 10, y: 284) 
     self.aaronHead.zPosition = 1.0 
     self.aaronBody.addChild(aaronHead) 

    } 
+1

正如appz你的生活指出的那樣,你可能會有一個強大的參考週期。搜索關於像無主自我,弱自我等術語。還可以看看文檔(作爲最佳參考)https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting。 html – Whirlwind

+0

如果你想要,你可以發佈你的一些場景的屬性以及你的視圖控制器的屬性,我可以看看是否可以找到任何明顯的保留週期。你說deinit沒有被調用的事實證明你在你的代碼中肯定有一個保留循環。你也可能希望做一個deinit工作的示例項目,並慢慢添加你的代碼直到deinit停止工作。這更多的是試驗和錯誤的方法,但它會挑釁地幫助你找到問題。 –

+0

謝謝Epic Byte,我只是添加了一些代碼。在我的每個SKScenes中,我爲每個角色的身體部位創建了大約12個左右的SKSpriteNodes,這些身體部位都是父對象。 – jwade502

回答

3

您已經發現問題:

在場景更改後,不會調用Deinit。

如果當scene確實改變舊場景的deinit未被調用,那就是問題所在。這意味着舊的場景仍在記憶中。

這可能是因爲您有一個強保留週期。這意味着你的場景的一個孩子(或者一個孩子的孩子......)對場景本身具有強引用

你必須找到參考,並與weak關鍵字聲明它。

+1

感謝您的提示appzYourLife。這是否意味着像SKNodes,SKSpriteNodes或SKLabelNodes這樣的東西需要設置爲弱? – jwade502

+0

@ jwade502:實際上,當你向你的場景(或另一個節點)添加一個'SKNode'(或'SKSpriteNode'或'SKLabelNode')時,你應該只寫'self.addChild(anotherNode)'。 SpriteKit會照顧參考。你是否在創建節點的屬性來引用其他節點? –

+0

僅用於紋理。我在我的init方法的頂部創建SKTexture屬性,然後在需要在SKSpriteNode上設置紋理時使用這些屬性。 – jwade502