0

CCScene の GameScene サブクラスの静的インスタンスを使用しています。GameScene からの呼び出し

[[CCDirector sharedDirector] replaceScene:[MainMenuScene scene]]; 

GameScene の dealloc メソッドをトリガーしません。

シーンを再度ロードすると (そして新しい GameScene が作成されます)、このメソッドが呼び出されます。

+(id) sceneWithId:(int)sceneId
{
    CCScene* scene = [CCScene node];
    GameScene* gameScene = [[self alloc] initWithId:sceneId];
    [scene addChild:gameScene z:0 tag:GameSceneLayerTagGame];
    return scene;
}

-(id) initWithId:(int)sceneId
{
    CCLOG(@"scene With id");
    if ((self = [super init]))
    {
        instanceOfGameScene = self;
        //ONLY NOW the previous object becomes unreferenced and the memory management system is allowed to deallocate it

メモリが「解放」されたときだけでなく、(静的) シーンを置き換えるたびに dealloc メソッドを強制的に呼び出す方法があるかどうかを理解したいと思いました。

または、代わりに、MainMenuScene に影響を与えたくない進行中のプロセスを停止するいくつかのクリーンアップ メソッドを作成する必要があります (たとえば、GameScene の dealloc メソッドにバックグラウンド ミュージックの停止メソッド呼び出しを配置し​​ましたが、バックグラウンド ミュージックも静的クラスであり、子として GameScene に追加されていない場合、MainMenuScene に戻って再生を続けます)。

したがって、私の簡単な修正提案は、次のようなことです。

    [self stopAllStuffInOtherStaticClassesThatAreRelatedOnlyToGameScene];
    [[CCDirector sharedDirector] replaceScene:[MainMenuScene scene]];

これは良いアプローチですか?

編集: dealloc メソッドにこのコードを追加するのが賢明なのはいつですか?

  [self removeAllChildrenWithCleanup:TRUE];
4

3 に答える 3

1

悪い習慣のにおいがします。ノードの静的インスタンスを保持しないでください。特にシーン階層の外ではありません。これは、cocos2d のメモリ管理の処理方法を壊すだけです。

状態を保存する必要がある場合は、この状態を別のクラスに保存しますが、シーンを変更するときは必ずシーンを手放してください。次に、シーンが再び開始されたときに状態を復元します。

dealloc メソッドを強制することはできません。そうしたいのは、コードの匂いのしるしです。ただし、ノードが子として削除される-(void) cleanup前後に初期化解除コードを実行するメソッドをオーバーライドできます。dealloc

編集: dealloc メソッドにこのコードを追加するのが賢明なのはいつですか?

[self removeAllChildrenWithCleanup:TRUE];

一度もない。これまで。

繰り返しますが、これを行う必要がある場合は、どこかにひどいバグがあります。この時点で、Cocos2D は子ノードを削除します。実際、cleanupメソッド中にそうします。cocos2d がノードの子を削除しないようにする 1 つの方法は、クリーンアップをオーバーライドし、[スーパー クリーンアップ] を呼び出さない場合です。

または、静的インスタンスとして保持する場合、実際にはクリーンアップ メソッドが呼び出されることはありません。さらに悪いことに、スケジュールされた更新とアクションを実行し続けることになります。

于 2012-09-12T21:00:19.083 に答える
0

あなたが困っているのは、ゲーム シーンを公開しないことです。として作成します

GameScene* gameScene = [[[self alloc] initWithId:sceneId] autorelease];

そして、それは正しく割り当て解除されます。

とにかく、ゲームシーンを他のシーンの子として作成する必要はないと思いますが、あなたのプロジェクトについて何か知らないかもしれません。

そして、「静的CCScene」の下で何を意味するのか理解できません

于 2012-09-12T20:33:30.557 に答える