3

我有一个 cocos2d 游戏,一旦游戏加载并运行,它的运行速度在 55 到 60fps 之间。

但是,由于我的菜单和游戏都使用了精灵表(每个一个),加载游戏时存在一个交叉点,这会导致内存警告,因为太多的大 png 加载到内存中。

我实现了一个简单的 CCScene 来转换到加载,(轻量级,允许菜单在继续加载主游戏场景之前解除分配)。

这非常有效。然而,我遇到了一个小障碍,在我的加载屏幕上,我的主角在加载这个词旁边旋转(以显示正在发生的事情)。

我发现我可以使用 NSThread 在不同的线程中加载游戏,让加载场景的动画继续畅通无阻(这带来了非常愉快的用户体验)。

但是,5-6/10 次,我收到此错误消息。

 Received memory warning. Level=1
 *** -[NSLock dealloc]: lock (<NSLock: 0x3ded70> '(null)') deallocated while still in use
  *** Break on _NSLockError() to debug.
  *** -[CFDictionary setObject:forKey:]: message sent to deallocated instance 0x3decc0

我正在使用此代码加载我的游戏。

在一个按钮内 -

NSThread* thread = [[[NSThread alloc] initWithTarget:self selector:@selector(goToNextScene) object:nil] autorelease];
[thread start];

在新线程中执行的方法 -

-(void) goToNextScene {

NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];

EAGLContext *k_context = [[[EAGLContext alloc]
                           initWithAPI :kEAGLRenderingAPIOpenGLES1
                           sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]] autorelease];
[EAGLContext setCurrentContext:k_context];

CCScene *gs = [GameEngine scene];

[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.5 scene:gs]];

[autoreleasepool release];

}

关于如何防止发生的任何事情发生的任何想法?

NSLock 是在 gameScene 尝试加载 gamesheet.plist(精灵表和坐标中的单个图像的帧名)时引起的

4

1 回答 1

2

你自己正确地诊断了它,虽然它不是被释放的 CCSpriteFrameCache 而是它所依赖的 CCTextureCache。

如果您从默认 cocos2d 模板创建项目,您的应用程序委托通过调用 [[CCDirector sharedDirector] purgeCachedData] 响应 applicationDidReceiveMemoryWarning。这反过来调用 [CCTextureCache purgeSharedTextureCache],它释放并清除共享缓存。这发生在您的主应用程序线程上,并且由于您的后台线程正在使用相同的缓存来存储它正在加载的纹理......繁荣。

最简单的解决方法是从您的应用委托中删除该 purgeCachedData 调用。您比操作系统更了解您的应用程序的内存消耗,因此与其让操作系统告诉您何时清除缓存,不如自己动手:仅当您知道已缓存的纹理不再使用时才调用 purgeCachedData。

根据您的简短描述,听起来您会在过渡/加载场景开始时这样做。请确保在创建用于进度动画的精灵后进行清除,以便保留它们的纹理。(清除调用不会删除当前正在使用的任何内容。)同样,请务必在启动后台线程之前进行清除,否则您将遇到与现在相同的崩溃。

于 2011-03-04T02:42:53.880 回答