我正在使用cocos2d并遇到以下问题:
第一次初始化场景时,我从以下开始:
[[CCDirector sharedDirector] runWithScene: [MenuScene node]];
在场景之间切换时,我总是使用:
[[CCDirector sharedDirector] replaceScene:[SceneName node]];
这工作正常,我能够从 MenuScene 切换到 GameScene,然后切换到 GameOverScene,然后返回到 MenuScene。但是,当我再次切换到 GameScene,然后再次切换到 GameOverScene 并尝试第二次切换到 MenuScene(第三次,如果算上初始 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
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
发布评论
评论(2)
此错误始终表明对象释放得太快或意外:
第一步是找出哪个对象(实例)被释放。为此,您应该转到产品 ->在 Xcode 中管理方案并双击(编辑)您的项目的方案。在诊断选项卡中,启用启用僵尸对象。下次发生错误时,您将获得有关已释放实例的更多信息。
由于这是相当低级的,并且表明 EAGLView 本身已被释放,因此您应该检查是否有任何可能释放视图的 CCDirector 调用。例如:
[[CCDirector sharedDirector] end];
另外,由于多次切换场景后出现这种情况,我怀疑你存在内存泄漏,可能会导致某些子系统因内存问题而关闭2 级警告。我建议在 appdelegate 的内存警告消息以及场景的 dealloc 方法中设置断点。如果场景的 dealloc 方法的断点从未被触发,那么您将泄漏整个场景,可能是因为保留周期。如果您将场景层次结构中的节点存储在自己的数组中,或者过度保留节点或多个节点相互引用,则很容易发生这种情况。
有关保留周期的更多信息此处,此处和此处 。
This error is always an indication that an object was released too soon, or accidentally:
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.
试试这个来切换场景:
[[CCDirector共享Director]replaceScene:[MenuSceen场景]];
和您添加的实现:
Try this one for switching between scenes:
[[CCDirector sharedDirector] replaceScene:[MenuSceen scene]];
and Implemention you add: