title: SpriteKit retaining memory after I leave game
body: <p>So I am developing an app that includes a SpriteKit game. What I noticed is that after I start and close the game the memory keeps increasing as shown on the graph below:</p>
  
  <p><a href="https://i.stack.imgur.com/N34e6.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/N34e6.png" alt="enter image description here"></a></p>
  
  <p>I am presenting the game from a View Controller using a modal presentation. So the question is:
  Is there a way to completely remove the scene from memory?</p>
  
  <p>I am tapping a close button on the View Controller to dismiss it. The <code>scene.quitGame()</code> method basically deallocates all nodes, actions etc. In an ideal world I wouldn't even need to do any of that as there would be a magic command that gets rid of the <code>SKScene</code> completely. </p>
  
  <pre><code>@IBAction func quit(_ sender: UIButton) {
      scene.quitGame()
      scene.removeFromParent()
      self.removeFromParentViewController()
      self.dismiss(animated: true, completion: nil)
      scene = nil
  }
  </code></pre>
  
  <p>EDIT: I present the scene from viewDidLoad with the following code:</p>
  
  <pre><code>scene = GameScene(size: view.bounds.size)
  let skView = view as! SKView
  skView.showsFPS = false
  skView.showsNodeCount = false
  skView.ignoresSiblingOrder = true
  scene.scaleMode = .resizeFill
  if let heroImage2 = heroImage2, let myImage = myImage, let monsterImage = monsterImage{
      scene.addPicture(img: heroImage2, myImage: myImage,monsterImage: monsterImage, bigMonsterImage: bigMonsterImage!)
  }
  skView.presentScene(scene)
  scene.viewController = self
  </code></pre>
  
  <p>EDIT 2 - I commented out the call to this method that includes a repeat forever action and the leak seems to go away</p>
  
  <pre><code>   func createHerosAction(duration: Double = 5.0){
          run(SKAction.repeatForever(
              SKAction.sequence([
                  SKAction.run(addHero),
                  SKAction.wait(forDuration: duration)
                  ])
          ), withKey:"createHeros")
      }
  
  
  
  func addHero() {
      // Create sprite
      if(heroImage == nil){
          heroImage = UIImage(named: "hero")
      }
  
      let Texture = SKTexture(image: heroImage!)
      let hero = SKSpriteNode(texture:Texture)
      hero.size.width = size.width * 0.17
      hero.size.height = hero.size.width
      hero.name = "hero"
      hero.zPosition = 2
  
      let heroSide = arc4random_uniform(2)
  
      hero.physicsBody = SKPhysicsBody(rectangleOf: hero.size) // 1
      hero.physicsBody?.isDynamic = true // 2
      hero.physicsBody?.categoryBitMask = PhysicsCategory.Hero // 3
      hero.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile // 4
      hero.physicsBody?.collisionBitMask = PhysicsCategory.None // 5
  
      let actualY = random(min: size.height*0.3 + hero.size.height/2 + size.height * 0.12, max: size.height - hero.size.height/2 - size.height * 0.15)
  
      let pointRightOfScreen = CGPoint(x: size.width + hero.size.width/2, y: actualY)
      let pointLeftOfScreen = CGPoint(x:  -hero.size.width/2, y: actualY)
  
      if(heroSide == 0){
          hero.position = pointRightOfScreen
      }else{
          hero.position = pointLeftOfScreen
      }
  
      addChild(hero)
  
      let actualDuration = random(min: CGFloat(2.0), max: CGFloat(5.0))
  
      var actionMove = SKAction()
  
      if(heroSide == 0){
          actionMove = SKAction.move(to: pointLeftOfScreen, duration: TimeInterval(actualDuration))
      }else{
          actionMove = SKAction.move(to: pointRightOfScreen, duration: TimeInterval(actualDuration))
      }
  
      let numberOfUpsAndDown = random(min: CGFloat(1.0), max: CGFloat(10.0))
      let variance = random(min: CGFloat(-70.0), max: CGFloat(70.0))
  
  
      let mvHero = moveHeroUpAndDown(node: hero, variance: variance,duration: actualDuration/numberOfUpsAndDown)
  
      let actionMoveDone = SKAction.removeFromParent()
  
  
      let loseLifeAction = loseLife(node: hero)
  
      hero.run(SKAction.sequence([actionMove, loseLifeAction, actionMoveDone]), withKey: "moveHero")
      hero.run(mvHero, withKey: "UpAndDown")
  
  
  }
  </code></pre>
  
  <p>EDIT 3: The leak seems to be on this SKAction that gets called above. After I removed this action the leak stopped.</p>
  
  <pre><code>   func loseLife(node: SKSpriteNode) -&gt; SKAction{
  
      let loseALifeAction = SKAction.run(){
  
          if(self.gamePaused == false){
              self.playSound(fileName: "losesound.wav")
  
              if(self.lives &gt; 0){
                  self.updateLives(newValue: self.lives - 1, lostLife: true)
                  //self.lives -= 1
              }
  
              print("lives: \(self.lives)")
  
              if(self.lives &lt;= 0){
                  print("hit me")
                  node.run(self.loseGame())
              }
          }
      }
      return loseALifeAction
  }
  </code></pre>