我有一个 cocos2d 游戏,一旦游戏加载并运行,它的执行速度在 55 到 60 fps 之间。
但是,由于我的菜单和游戏都使用 Sprite 表(每个 Sprite 表一个),因此在加载游戏时会出现一个交叉点,这会导致内存警告,因为内存中加载了太多大的 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( Sprite 表中各个图像的帧名称和坐标)时引起的
最佳答案
您自己诊断正确,尽管被释放的不是CCSpriteFrameCache,而是它所依赖的CCTextureCache。
如果您从默认的 cocos2d 模板创建项目,您的应用程序委托(delegate)将通过调用 [[CCDirector sharedDirector] purgeCachedData] 响应 applicationDidReceiveMemoryWarning。这又会调用 [CCTextureCache purgeSharedTextureCache],它会释放并清空共享缓存。这发生在您的主应用程序线程上,并且由于您的后台线程正在使用相同的缓存来存储它正在加载的纹理......繁荣。
最简单的修复方法就是从应用程序委托(delegate)中删除 purgeCachedData 调用。您比操作系统更了解应用程序的内存消耗,因此不要让操作系统告诉您何时清除缓存,而是您自己执行:仅当您知道缓存了不再使用的纹理时才调用 purgeCachedData。
根据您的简短描述,听起来您会在过渡/加载场景开始时执行此操作。请务必在创建用于进度动画的 Sprite 之后进行清除,以便保留它们的纹理。 (清除调用不会删除当前正在使用的任何内容。)同样,请务必在启动后台线程之前进行清除,否则您将遇到与之前相同的崩溃现在看到了。
关于iphone - 游戏中的加载屏幕(确保动画在转换过程中不会卡顿),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5153924/