Cocos2d: проблема с памятью при переключении между сценами ([EAGLView swapbuffers]) - PullRequest
0 голосов
/ 07 ноября 2011

Я использую cocos2d и столкнулся со следующей проблемой: При первой инициализации сцены я начинаю с:

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

При переключении между сценами я всегда использую:

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

Это работает нормально, я могу переключиться с MenuScene на GameScene, затем на GameOverScene и затем обратно на MenuScene. Но когда я снова переключаюсь на GameScene, затем снова на GameOverScene и пытаюсь переключиться на MenuScene во 2-й раз (3-й раз, если вы учитываете начальный вызов runWithScene), приложение вылетает, и я получаю сообщение об ошибке:

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

Из того, что я прочитал, всегда должна существовать хотя бы одна сцена (что должно быть в данном случае?). Я также пытался оставить исходную сцену нетронутой, используя pushScene для всех других сцен и popScene в конце, чтобы вернуться к MenuScene, но я получаю ту же ошибку таким же образом, также и во 2-й серии.

Моя реализация MenuScene выглядит следующим образом:

@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

Ответы [ 2 ]

1 голос
/ 07 ноября 2011

Эта ошибка всегда указывает на то, что объект был выпущен слишком рано или случайно:

message sent to deallocated instance

Первый шаг - выяснить, какой объект (экземпляр) был освобожден. Для этого вам нужно перейти в Продукт -> Управление схемами в Xcode и дважды щелкнуть (отредактировать) схему для вашего проекта. На вкладке Диагностика включите Включить объекты-зомби . В следующий раз, когда произойдет ошибка, вы получите больше информации об освобожденном экземпляре.

Так как это довольно низкий уровень и указывает, что сам EAGLView освобожден, вам следует проверить все вызовы CCDirector, которые могут освободить представление. Например: [[CCDirector sharedDirector] end];

Кроме того, поскольку это происходит после многократного переключения сцен, я подозреваю, что у вас есть утечка памяти, которая может привести к отключению некоторых подсистем из-за предупреждения памяти уровня 2. Я рекомендую установить точку останова в памяти приложения appdelegate. предупреждающее сообщение, а также в методе dealloc ваших сцен. Если точка останова метода dealloc сцены никогда не срабатывает, значит, вы пропускаете всю сцену, возможно, из-за цикла сохранения. Это может легко произойти, если вы сохраняете узлы в иерархии сцены в своем собственном массиве или чрезмерно сохраняете узлы или несколько узлов, которые сохраняют ссылку друг на друга.

Подробнее о циклах сохранения здесь , здесь и здесь .

0 голосов
/ 07 ноября 2011

Попробуйте это для переключения между сценами: [[CCDirector sharedDirector] replaceScene: [Сцена MenuSceen]];

и Реализация вы добавляете:

 +(id) scene
{
CCScene *scene = [CCScene node];
MenuSceen *layer = [MenuSceen node];
[scene addChild: layer];
return scene;
}
...