dannybess
dannybess

Reputation: 599

SKScene getting slower after every restart

This is my code. I assume this because deinit is never called, and every time the user starts playing (GameScene), the memory jumps from 20 MB to 40 MB to 60, etc. and the FPS goes down after every time the user dies and restarts the game.

Does anyone know why?

GameViewController.swift
import UIKit
import SpriteKit

extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file as String, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}


class GameViewController: UIViewController{

    @IBOutlet var skSceneReal: SKView!


    override func viewDidLoad() {
        super.viewDidLoad()

    }
    override func viewWillAppear(animated: Bool) {
        if((self.skSceneReal) != nil)
        {
            if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
                // Configure the view.
                var skView = self.view as! SKView
                skSceneReal.showsFPS = false
                skSceneReal.showsNodeCount = false

                /* Sprite Kit applies additional optimizations to improve rendering performance */
                skSceneReal.ignoresSiblingOrder = true
                /* Set the scale mode to scale to fit the window */
                scene.scaleMode = .AspectFill
                scene.viewController = self
                skSceneReal.presentScene(scene)
            }

        }
    }

    deinit
    {
        println("deinit worked")
    }

    override func viewWillDisappear(animated: Bool) {
        self.skSceneReal.removeFromSuperview()
        self.skSceneReal = nil;
    }

    override func shouldAutorotate() -> Bool {
        return true
    }

    override func supportedInterfaceOrientations() -> Int {
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
            return Int(UIInterfaceOrientationMask.AllButUpsideDown.rawValue)
        } else {
            return Int(UIInterfaceOrientationMask.All.rawValue)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }




}


GameScene.swift
...
var gameEnding = false;
func gameOver(){
    if(!gameEnding) {
        gameEnding = true;
        // Deallocate/reset the view/scene.
        // ???? DONT KNOW WHAT TO DO ????
        // Present move segue.(Created in storyboard) Source: GameVC, Destination: GameOverVC
        self.viewController?.performSegueWithIdentifier("move", sender: self)
    }


}

And there's a modal segue back to GameViewController from a button in GameOverViewController (created in Storyboard).

Upvotes: 0

Views: 410

Answers (1)

Philip
Philip

Reputation: 2285

I got the same problem. I fixed it by nulling all my nodes on the scene and instead of showing a UIViewController I am showing another SKScene instead. This seemed to solve the problem and deallocating the GameScene correctly.

This is my game over method:

- (void) gameOver {
    [self removeAllActions];
    [self removeAllChildren];


    SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];

    SKScene *newScene;
        newScene = [[GameOverScene alloc] initWithSize:self.size andNewHighscore:score];


    [self.view presentScene:newScene transition: reveal];    
}

Upvotes: 1

Related Questions