spritekit kit game cross ios xcode swift memory sprite-kit

ios - game - Aumento de memoria en SpriteKit aunque se haya llamado a removeAllChildren



swift sprite kit (1)

He estado intentando arreglar un gran aumento de memoria en SpriteKit durante muchas semanas pero no he encontrado ninguna solución. He probado casi todos los métodos que he encontrado en línea para administrar la memoria en SK, pero todavía tengo problemas. Aquí está mi situación:

Primero presento SKScene "HomeScreen" y desde allí estoy cambiando las escenas de la página con un UIButton en mi View Controller de esta manera:

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

Y aquí está mi gráfico de memoria de Xcode:

Como puede ver, mi memoria para HomeScreen (HS) comienza en 38.1 y para cuando he recorrido todas las escenas y regreso a la pantalla de inicio, termina en 112. También cargué cada página individualmente y grabé la memoria para confirmar El aumento.

En cada SKScene, cargo varios objetos y luego en willMoveFromView los elimino así:

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

Aquí hay un poco más de información: - No se está llamando a Deinit después de que una escena cambia.

  • No tengo filtraciones cuando pruebo la aplicación con Instruments.

  • Todas las SKTextures se cargan primero como UIImages utilizando stringByAppendingPathComponent.

  • Todos los métodos de willMoveFromView contienen removeAllActions y removeAllChildren.

¿Alguien sabe por qué mi memoria está aumentando?

Actualizar un poco más de código de muestra

Aquí es cómo cargo mi skView en viewDidLoad:

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

Y aquí hay un poco de mi 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) }


Ya encontraste el problema:

Deinit no es llamado después de que una escena cambia.

Si cuando una scene cambia no se deinit la deinit de la escena anterior, ese es el problema. Significa que la escena anterior aún está en la memoria.

Esto probablemente esté sucediendo porque tienes un fuerte ciclo de retención . Esto significa que un niño (o un niño de un niño ...) de su escena tiene una fuerte referencia a la escena misma.

Debe encontrar esa referencia y declararla con la palabra clave weak .