【问题标题】:Cocos2d: Memory issue when switching between scenes ([EAGLView swapbuffers])Cocos2d:场景切换时的内存问题([EAGLView swapbuffers])
【发布时间】:2011-12-23 07:25:24
【问题描述】:

我正在使用 cocos2d 并遇到以下问题: 我第一次初始化场景时,我从以下内容开始:

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

在场景之间切换时,我总是使用:

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

这很好用,我可以从 MenuScene 切换到 GameScene,然后切换到 GameOverScene,然后再切换回 MenuScene。但是,当我再次切换到 GameScene,然后再次切换到 GameOverScene 并尝试第二次切换到 MenuScene(第 3 次,如果您计算初始 runWithScene 调用)时,应用程序崩溃并且我收到错误消息:

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

根据我的阅读,应该至少存在一个场景(这里应该是这种情况?)。我还尝试通过对所有其他场景使用 pushScene 并在最后使用 popScene 返回到 MenuScene 来保持初始场景不变,但是我在第二次运行时也遇到了同样的错误。

我的 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

【问题讨论】:

    标签: iphone memory cocos2d-iphone eaglview


    【解决方案1】:

    此错误始终表明对象被释放得太早或意外:

    message sent to deallocated instance
    

    第一步是确定哪个对象(实例)被释放。为此,您应该转到 Xcode 中的 Product -> Manage Schemes 并双击(编辑)您项目的方案。在Diagnostics标签中,开启Enable Zombie Objects。下次发生错误时,您将获得有关已释放实例的更多信息。

    由于这是相当低级的并且表明 EAGLView 本身已被释放,因此您应该检查对 CCDirector 的任何可能释放视图的调用。例如:[[CCDirector sharedDirector] end];

    另外,由于多次切换场景后会出现这种情况,我怀疑您有内存泄漏,可能会由于级别 2 的内存警告而导致某些子系统关闭。我建议在 appdelegate 的内存中设置断点警告消息以及场景的 dealloc 方法中。如果场景的 dealloc 方法的断点从未被触发,那么您正在泄漏整个场景,可能是因为保留循环。如果您将场景层次结构中的节点存储在您自己的数组中,或者过度保留节点或多个节点相互保持引用,则很容易发生这种情况。

    更多关于保留周期 hereherehere

    【讨论】:

    • 我已经启用了 NSZombie,但我没有获得更多信息。我确定我没有取消分配视图,所以我想这与保留周期有关。我现在要调查一下。
    • AppDelegate 在应用崩溃之前没有收到任何内存警告。
    【解决方案2】:

    试试这个在场景之间切换: [[CCDirector sharedDirector] replaceScene:[MenuSceen 场景]];

    和你添加的实现:

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

    【讨论】:

    • 这正是我的 init() 方法中发生的事情,只是实现了一点不同..
    猜你喜欢
    • 1970-01-01
    • 2015-11-16
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多