2012-02-11 3 views
5

大きな問題があります。これはその場合です:多くのシーンを持つCocos2Dプロジェクトは、メモリを適切に解放しません。

  • 10シーンでCocos2Dの素晴らしいプロジェクトをお持ちですか?各シーンは、巨大なスプライトを持つ本のページです。それはKobold2D 1.0.2実装を使用します。
  • すべてのページには、レイヤーカラーを使用して共通のメニューを配置するために、シングルトンクラス内に共通のオブジェクトがあります。
  • スプライトはPVR.CCZ RGBA4444のTexturePackerで、iPadのメモリ はスプライトシートがロードされるたびに16-20Mbくらいです。
  • 私はCCTransitionTurnPageをreplaceSceneのために次のものに使う。
  • 各ページ(クラス)のinitメソッドで、テクスチャとFrameFileを読み込みます。
  • 各ページ(クラス)のonExitメソッドで、テクスチャとframeFileをアンロードします。私はdumpCachedTextureInfoを使って、テクスチャがメモリから完全にロードされ、アンロードされると言います。
  • もちろん、すべてのオブジェクトを子から削除します。私のすべてのスプライトは、クラスのすべてのメソッドでアクセスする必要があるため、.hのインターフェースセクションで宣言された共通変数です。
  • は私のプロジェクトは、ARCプロジェクトのKobold2Dの統合で作られている(ただし、添付Kobold2Dプロジェクトは、ARC互換性の問題のために有効になっていません知っている)私はプロジェクトを開始するとき事実がある

、すべてが完璧けどメモリ思えます私が作ったシーン(ページ)ごとに増えています。インストゥルメント、XcodeまたはiPad自体がメッセージを表示せずにアプリケーションをハングアップします(最終的なメモリ不足警告があるインストゥルメントを除く)。Page 7:30Mb。、Page 2:40、Page 3:54、Page 4: 。

なぜ各シーンの後にメモリが解放されないのですか?たぶんそれはARCとno super dealloc変数のためです。なぜテクスチャが完全にアンロードされているように見えますが、クラッシュまでメモリが制御されずに伸びているので、アンロードがないようです。

+0

シーンのdeallocメソッドにブレークポイントを設定すると、deallocが呼び出されずに保持サイクルがある場合(ARCはそれを防ぐことができません。参照:http://stackoverflow.com/questions/3634435/can-any) -one-explain-retain-cycle-with-example-code対象-c-and-how-can-we)を使用することができます。特に、CCNode *プロパティのどれも強い属性や弱い属性を持たないことを確認するには、assignに設定する必要があります。 – LearnCocos2D

+2

最後に、シーンのこの保持サイクルのために、ARCを無効にする必要があります。私は各シーンの実際のデアロックを行うための解決策を見つけることができず、私はARCを無効にする必要があります。私がそれをするとき、すべてがうまくいく。 RemoveAllTexturesはメモリをフリーズし(ARCは使用しないで)、スーパーdeallocは完全に動作します。 ARCを有効にしたときにdeallocが無効になり、onExitを使用してテクスチャをアンロードしてメモリをフリーズしましたが、動作しませんでした。あなたの助けをありがとう! –

+2

ARCを無効にする可能性が最も高いのは、コードのバグの振る舞いを変更するだけです。特に、循環参照ARCがある場合やARCで違いが生じない場合は、オブジェクトを静かに漏らしている可能性があります。 – LearnCocos2D

答えて

10

私は、メモリの保持と同様の問題を抱えていて、計測器に漏れはありませんでした。

-(void) onExit { 
    //unschedule selectors to get dealloc to fire off 
    [self unscheduleAllSelectors]; 
    //remove all textures to free up additional memory. Textures get retained even if the sprite gets released and it doesn't show as a leak. This was my big memory saver 
    [[CCTextureCache sharedTextureCache] removeAllTextures]; 
    [super onExit]; 
} 

これを実装した後、私の記憶では、すべてのreplaceScene後にリリースされました:と呼ばれていたすべてのシーンの.mファイルに次のように私が書いたまで(無効)にdeallocがさえ呼ば取得する - 私は得ることができませんでした。これがあなたに役立つことを願っています。

+2

私はいつも使用しています [[CCTextureCache sharedTextureCache] removeUnusedTextures]; Cocos2Dは、テクスチャが実際には使用されていないことを理解し、それを削除すると考えています。それを確実に判断することはできませんので、removeAllTexturesはメモリの問題を防ぐのに適しています。 – axello

3

数ヶ月の作業の後、私はCocos2Dで最も重要な教訓を学びました。 CCArrayまたはNSArrayまたはNSDictionaryにCCNodeオブジェクトを置くと、保持が1つ増えます。これは、CCLayerまたはCCScene deallocの前にこのオブジェクトからオブジェクトを解放する必要があることを意味します。

[array removeAllObjects]または[dictionary release]を - (void)クリーンアップに配置し、オブジェクトがすべて削除された後に[スーパークリーンアップ]を実行する必要があります。

一方、 - (void)onExitでは、インスタンスからすべてのスケジューラを削除する必要があります。スケジューラそのものだけでなく、任意のCCNodeでstopAllActionsを忘れないでください。しかし、注意深く、CCNode(スプライトなど)からのアクションの停止は、removeAllObjectsの前にクリーンアップする必要があるためです。

注意:CCLayerまたはCCSceneが正しく削除されない場合、SimpleAudioEngineはオーディオも解放しません。

+0

この式は、ARCプロジェクトまたは非ARCプロジェクトの両方に適用されます。 :) –