3

私はcocos2dゲームを持っています。ゲームがロードされて実行されると、55〜60fpsで実行されます。

ただし、メニューとゲームの両方にスプライトシート(それぞれ1つ)を使用しているため、ゲームをロードするときにクロスオーバーのポイントがあり、メモリにロードされる大きな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 呼び出しを削除することです。OS よりもアプリのメモリ消費をよく理解しているため、OS にキャッシュを削除するタイミングを指示させるのではなく、自分で実行してください。今後使用しないテクスチャがキャッシュされていることがわかっている場合にのみ、purgeCachedData を呼び出します。

あなたの簡単な説明から、トランジション/ローディング シーンの開始時にそれを行うように思えます。プログレス アニメーションに使用するスプライトを作成したは、必ずパージを実行して、テクスチャが保持されるようにしてください。(purge 呼び出しは、現在使用中のものを削除しません。) 同様に、バックグラウンド スレッドを開始する前に必ず purge を実行してください。そうしないと、今見ているのと同じクラッシュが発生します。

于 2011-03-04T02:42:53.880 に答える