9
votes

I use a dispatch_once NSObject to create data pointers. So all game asset pointers are made when the main viewcontroller appears. In order to play a game, the user taps a UIButton corresponding to a particular level on a UIViewController. Let me call it LevelSelectionController. When the game is over, the user will tap a label (SKLabel). And all actions and nodes will be removed.

[self removeAllActions];
[self removeAllChildren];
[self removeFromParent];

Moreover, an SKScene subclass for a particular level delegates the task of returning the user to LevelSelectionController to the viewcontroller presenting game SKView as follows.

- (void)closeScene {
    SKView *spriteView = [[SKView alloc] init];
    [spriteView presentScene:nil];
    [self.navigationController popViewControllerAnimated:YES];
}

The only issue that I have is that the memory remains high when the user leaves the game scene (SKScene). The game requires a lot of assets. So when the game starts, the memory usage will jump to 200 MB. When the user returns to the original level selection view controller, the game simulator is still consuming 200 MB according to Activity Monitor. When the user enters a different level, the memory usage will jump by another 10 MB. So how can I release the memory for the last game once the user leaves SKScene?

I'm using ARC. The Xcode version is 5.1. The development target is iOS 7.1.

Thank you for your help.

-- Edit 1 --

I'm silly. I know what the problem is. When I close the scene, I'm creating a new SKView, which I then set it to nil to get of out the current scene. It works. But that should not be the way of doing it. Instead, I need to set the current SKView to a variable before presenting it. When I close the scene, I need to set that variable to nil. Hmm... I wasn't thinking.

-- Edit 2 -- There's little change when the current scene is presented with nil. Removing it from removeFromSuperview doesn't do much.

2
I don't think it's a good idea to manage multiple SKView in an iOS project, even if you're replacing views. One reason is that the various resource caches may be associated with the view, and it could be costly (both performance and memory consumption wise) to swap out views. Instead use a single view and use scene transitions to change scenes. This is how Sprite Kit is intended to be used.LearnCocos2D

2 Answers

2
votes

It has been noticed by a few people on SO that an SKScene gets deallocated when the containing SKView is removed from it's superview.

Have a look at these questions and their answers:

Deallocate SKScene after transition to another SKScene in SpriteKit

iOS 7 Sprite Kit freeing up memory

Also, try modifying the closeScene method like so:

- (void)closeScene {
    SKView *spriteView = (SKView*)self.view;
    [spriteView presentScene:nil];
    [self.navigationController popViewControllerAnimated:YES];
}
0
votes

Put NSLog() to SKScene's dealloc method to be sure that it's deallocating.

Also, resources may be not released just after reference count of your scene reaches 0. Due to internal optimizations assets may stay in memory until receiving Memory warning signal.