2012-01-09 4 views
0

グローバルクリーンアップ機能を使用して、MovieClipまたはTextFieldを削除しようとしています。私はクリップを直接参照しないでクリップを削除したい。どんな助けでも大歓迎です。ここでガベージコレクションのクリーンアップ関数の作成に問題があります。[例の中の]

var clip:Sprite = new Sprite(); 
clip.graphics.beginFill(0x000000, 1) 
clip.graphics.drawRect(0,0,100,100) 
clip.graphics.endFill() 
clip.name = "clip" 
addChild(clip); 

cleanup(clip) 

function cleanup(mc):void { 
    removeChild(mc.parent.getChildByName(mc.name)); 
    mc = null 

    // clip is removed and traces as [object Sprite] 
    trace(clip) 

    // 
    addChild(clip); 
    removeChild(clip) 
    clip = null 

    // clip is removed and traces as null. 
    trace(clip) 
} 

は、FLA(Flash CS4の)です:http://dl.dropbox.com/u/4725599/test-cs4.zip

答えて

3

あなたはスコープの誤解があるようです。あなたはSpriteを作成するとき、あなたはSpriteに必要なメモリを割り当て、clip変数に代入している、

function cleanup(mc):void { 
    removeChild(mc.parent.getChildByName(mc.name)); // removes the "clip" sprite 
    mc = null; // nulls the local var "mc", which essentially does nothing 

    addChild(clip);  // re-add the "clip" sprite 
    removeChild(clip) // remove the "clip" sprite 
    clip = null;  // null the "clip" sprite, removing the last reference to the memory allocated for the sprite 
} 

を基本的に:私はあなたがやっていることを説明しようとするでしょう。スプライトに参照が1つあります。

次にステージに追加します。これにより新しい参照が作成されるため、スプライトに2つの参照が追加されました。それでおしまい。

の変数は一時変数です。関数が終了するとクリーンアップされるので、気にする必要はありません。基本的にはSpriteにガベージコレクションのタグを付けるには、clip変数とステージの2つの参照を削除する必要があります。だからあなたは単にする必要があります:

clip.parent.removeChild(clip); 
clip = null; 

そしてそれは完了です。そのうち

チェック:http://divillysausages.com/blog/tracking_memory_leaks_in_as3(免責事項:私のサイト)あなたのメモリは通常、あなたがこのクラスに基づいて動作しますAS3

編集 にどのように動作するかの良い説明を与える必要があります。私のすべてのクラスでは、クラスをクリーンアップするために呼び出すことができるdestroy()関数を実装しています(子、イベントリスナー、他のオブジェクトへの参照など)。コードdestroy()を呼び出すコードでは、オブジェクトが何をしているか、またどのように動作しているかは気にしません。後でオブジェクトがガベージコレクションに適していることがわかります。

一般的な原則として、何かを作成するオブジェクトもそれを破壊する責任があります。

+0

これはすべて意味がありますが、機能を通してMovieClip/Spriteを渡そうとするとどうなりますか?私はクリップが渡されているかどうかを確認するためにコンディションの束を設定することができますね!= null。それを行うためのより良い方法があるはずですか? – Tom

+0

私はいくつかの点で私の答えを更新しました。具体的には、エラーが発生するかどうかを確認します。たとえば、親があるかどうか最初にチェックすることなく、 'removeChild()'を呼び出すことはありません。 – divillysausages

+0

'cleanup()'に渡されるものはすべてあなたのコードの構造に依存していることを確認してください。あなたがよく定義された状態(init、play、destroy)を持っているなら、あなたはこの問題を起こすべきではありません。同じオブジェクトを2回クリーンアップしようとすると、構造に問題があります。それは、チェックを追加することは決して傷つけることはありません;)それは、メインブラウザでデバッグプレーヤーを実行する私たち全員のために役立ちます – divillysausages

1

親オブジェクトの表示リストから表示オブジェクトを削除することは、十分ではないことに注意してください。 ガベージコレクタの資格を得るには、そのオブジェクトに割り当てられたすべてのリスナも削除する必要があります。また、オブジェクトが他の場所、たとえば配列内で参照されている場合、オブジェクトは正しくガベージコレクションされません。 私が言っていることは、おそらくGC用の関数を書くのは簡単ではないということです。私は通常、すべてのオブジェクトを手動で処分します。 お手伝い願います!

関連する問題