iphonememorycocos2d-iphoneeaglview

Cocos2d: Memory issue when switching between scenes ([EAGLView swapbuffers])


I'm using cocos2d and ran into the following problem: The first time I initialize a scene I start with:

[[CCDirector sharedDirector] runWithScene: [MenuScene node]];

When switching between scenes, I always use:

[[CCDirector sharedDirector] replaceScene:[SceneName node]];

This works fine, I'm able to switch from the MenuScene to the GameScene, then to the GameOverScene and then back, to the MenuScene. But when I switch to the GameScene again, then to the GameOverScene again and try to switch to the MenuScene for the 2nd time (3rd time, if you count the initial runWithScene call) the app crashes and I get the error message:

*** -[EAGLView swapBuffers]: message sent to deallocated instance 0x9614f80
sharedlibrary apply-load-rules all

From what I've read, there should exist at least one scene at all times (which should be the case here?). I also tried to leave the initial scene untouched by using pushScene for all other scenes and popScene at the end to go back to the MenuScene, but I'm getting the same error this way, also on the 2nd run.

My implementation of the MenuScene looks as follows:

@implementation MenuScene
@synthesize menuLayer = _menuLayer;

- (id)init {

    if ((self = [super init])) {
        self.menuLayer = [MenuLayer node];
        [self addChild:_menuLayer];
    }
    return self;
}

- (void)dealloc {
    [_menuLayer release];
    _menuLayer = nil;
    [super dealloc];
}

@end

Solution

  • This error is always an indication that an object was released too soon, or accidentally:

    message sent to deallocated instance
    

    The first step is to figure out which object (instance) was deallocated. To do that, you should go to Product -> Manage Schemes in Xcode and double-click (edit) the scheme for your project. In the Diagnostics tab, turn on Enable Zombie Objects. Next time the error occurs you'll get more information about the deallocated instance.

    Since this is pretty low-level and indicates that the EAGLView itself is deallocated, you should check for any calls to CCDirector that might deallocate the view. For example: [[CCDirector sharedDirector] end];

    In addition, since this happens after switching the scenes multiple times, I suspect that you have a memory leak which might cause some subsystems to shutdown due to a memory warning of level 2. I recommend to set a breakpoint in the appdelegate's memory warning message as well as in the dealloc method of your scenes. If the breakpoint of a scene's dealloc method is never triggered, then you're leaking the whole scene, probably because of a retain cycle. This can easily happen if you store nodes in the scene hierarchy in your own array or over-retain nodes or multiple nodes who keep a reference to each other.

    More on retain cycles here, here and here.