Memory Increase in SpriteKit even though removeAllChildren called

故事扮演 提交于 2020-01-13 05:10:08

问题


I've been trying to fix a huge memory increase in SpriteKit for many weeks now but have found no solution. I have tried just about every method that I've come across online for managing memory in SK but am still having troubles. Here's my situation:

I first present the SKScene "HomeScreen" and from there I am changing Page scenes with a UIButton in my View Controller like so:

 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
    }
}

And here is my memory graph from Xcode:

As you can see, my memory for HomeScreen (HS) starts at 38.1 and by the time I have cycled through all the scenes and come back to the Home Screen it ends at 112. I also loaded each page individually and recorded the memory to confirm the increase.

In each SKScene, I load various objects and then in willMoveFromView I am removing them as so:

    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()
}

Here's a little more info: - Deinit is not being called after a scene changes.

  • I have no leaks when testing the app with Instruments.

  • All SKTextures are loaded first as UIImages using stringByAppendingPathComponent.

  • All willMoveFromView methods contain removeAllActions and removeAllChildren.

Does anyone know why my memory is increasing?

Update A little more sample code

Here is how I load my skView in viewDidLoad:

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

And here is a bit from my Page01 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:


You already found the problem:

Deinit is not being called after a scene changes.

If when a scene does change the deinit of the old scene is not called then that's the problem. It means that the old scene is still in memory.

This is probably happening because you have a strong retain cycle. This means that a child (or a child of a child...) of your scene has a strong reference to the scene itself.

You must find that reference and declare it with the weak keyword.



来源:https://stackoverflow.com/questions/34052659/memory-increase-in-spritekit-even-though-removeallchildren-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!