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
.