I am using some static instance of a GameScene subclass of CCScene. Calling from GameScene
[[CCDirector sharedDirector] replaceScene:[MainMenuScene scene]];
doesn’t trigger the dealloc method of the GameScene.
The method is called once I load again the scene (and a new GameScene is created):
+(id) sceneWithId:(int)sceneId
{
CCScene* scene = [CCScene node];
GameScene* gameScene = [[self alloc] initWithId:sceneId];
[scene addChild:gameScene z:0 tag:GameSceneLayerTagGame];
return scene;
}
-(id) initWithId:(int)sceneId
{
CCLOG(@"scene With id");
if ((self = [super init]))
{
instanceOfGameScene = self;
//ONLY NOW the previous object becomes unreferenced and the memory management system is allowed to deallocate it
I wanted to understand if there is a way of forcing the dealloc method to be called every time I replace a (static) scene and not only when the memory gets “freed”.
Or, if I should instead, write some cleanups methods that stops ongoing processes that I don’t want to effect the MainMenuScene (e.g. I have put a stop background music method call in the dealloc method of GameScene but as also the background music is in a static class -and is not added to GameScene as child- then it keeps playing once back in the MainMenuScene).
My quick fix proposal hence is to do something like this:
[self stopAllStuffInOtherStaticClassesThatAreRelatedOnlyToGameScene];
[[CCDirector sharedDirector] replaceScene:[MainMenuScene scene]];
Is this a good approach?
EDIT: when is sensible to add this code in the dealloc method?
[self removeAllChildrenWithCleanup:TRUE];
I smell bad practice. Never, ever keep a static instance of a node around. Especially not outside the scene hierarchy. It just breaks cocos2d’s way of handling memory management.
If you need to preserve state, save this state to a separate class but by all means let the scene go when you change scenes. Then restore the state when the scene inits again.
You can not force the dealloc method. Wanting to do so is a sign of code smell. You can however override the
-(void) cleanupmethod to run de-initialization code beforedeallocand after the node has been removed as child.Never. Ever.
Again, if you find you need to do this, there’s a terrible bug somewhere. Cocos2D will have removed the child nodes by this time. In fact, it does so during the
cleanupmethod, one way to cause cocos2d not to remove a node’s children is when you override cleanup and not call [super cleanup].Or perhaps when you keep it as a static instance, so it’ll never actually call the cleanup method. And even worse would then continue to run scheduled updates and actions.