2

質問1:

次の例では、iveがfoundMicにリスナーを追加しました。私の質問は、foobar.initMic();を再実行するかどうかです。マイクを再初期化するために、デッドイベントリスナーがメモリに浮かんでしまい、ガベージコレクションによってピックアップされますか?.getMicrophone()を呼び出すと、同じリソースがfoundMicに再接続されるだけですか、それとも古いfoundMicが破棄され、メモリ内にfoundMicの新しいインスタンスが作成されますか。

まったく同じfoundMicの場合と同様に、イベントリスナーの追加はサイレントに失敗し、2番目のリスナーは作成されません。ただし、foundMicが新しいインスタンスになると、新しいリスナーが作成されます。次に、ガベージコレクションについての質問に戻りますが、クリーンアップのために参照されていないと見なされますか?

public class foobar {

    public static var foundMic:Microphone = null;

    public static function initMic():void {
        foundMic = Microphone.getMicrophone();
        foundMic.codec = SoundCodec.SPEEX;
        foundMic.setSilenceLevel(0, 5000);
        foundMic.gain = 50;
        foundMic.setUseEchoSuppression(true);
        foundMic.soundTransform.volume = 1;
        foundMic.addEventListener(StatusEvent.STATUS, onMicStatusEvent);
        return;
     }

    public static function onMicStatusEvent(event:StatusEvent):void {
        if (foundMic && !foundMic.muted) someButton.enabled = true;
        else someButton.enabled = false;
        return;
    }

} // END CLASS

質問2:

質問1に基づいて、リスナーを追加する直前に削除リスナーを追加した場合、メソッドが最初に実行されたときに作成された2回目の実行時に実際にリスナーが削除されますか?または、そのfoundMicはすでに.getMicrophone()から新しいインスタンスであるため、最初のリスナーがfoundMicの前のインスタンスに関連付けられたメモリにすでにフローティングしているため、何も削除されませんか?

    public static function initMic():void {
        foundMic = Microphone.getMicrophone();
        .
        .
        .
        foundMic.removeEventListener(StatusEvent.STATUS, onMicStatusEvent);
        foundMic.addEventListener(StatusEvent.STATUS, onMicStatusEvent);
        return;
     }
4

2 に答える 2

0

イベントリスナーで何が起こるかを次に示します。への参照をsomeObject.addEventListener('someEvent', someFunction)渡します。ActionScript でスコープが機能する方法により、関数はそれを作成したコードのスコープ内のすべてにアクセスできます。したがって、 を呼び出すまで、関数が存在するインスタンスは、メモリ内にある限りメモリ内に保持されます。someObjectsomeFunctionremoveEventListenersomeObject

ただし、静的関数を使用することにより、クラスが最初に参照されてからswfがコンピューターのメモリから取り出されるまでリスナーが存在するため、インスタンスはありません。FooBar

リスナーを追加する前にリスナーを削除しても、実質的な効果はありません。これは、まったく同じ関数がまったく同じオブジェクトに渡され、関数が 2 回呼び出されることはないためです。

イベント リスナーの仕組みの詳細については、このブログ投稿をご覧ください。

于 2012-06-26T23:11:09.037 に答える
0

foundMic には、Microphone への参照である新しい値が割り当てられるだけです。何もガベージ コレクションされるべきではありません。

ガベージ コレクターが起動する必要があるのは、次のような場合です。

var someVar:Sprite;
for(var i:int = 0; i < 5; i++)
{
    someVar = new Sprite();
}

この場合、5 つの新しい Sprite オブジェクトを作成しましたが、someVar 変数に割り当てられたのは 1 つだけになりました。残りの 4 つは、変数によって参照されていないため、ある時点でガベージ コレクションを取得する必要があります。

質問 2 に関しては、最初に initMic() を呼び出したときにエラーが発生するはずです。その時点ではまだ onMicStatusEvent リスナーがないからです。イベント リスナーを削除する前に、まずテストして存在するかどうかを確認します。

if(foundMic.hasEventListener(StatusEvent.STATUS)
{
    foundMic.removeEventListener(StatusEvent.STATUS, onMicStatusEvent);
}
foundMic.addEventListener(StatusEvent.STATUS, onMicStatusEvent);

このコードは常に、イベント リスナーが存在する場合は最初にそれを削除し、次に新しいイベント リスナーを追加します。ただし、この場合、 addEventListener 自体は問題なく動作するはずなので、これの理由はわかりません。複数の呼び出しはすべて同じオブジェクトに対して行われるため、 initMic() を何回呼び出しても、イベントは 1 つだけです。リスナーが実行中 - リスナーを手動で削除してから再作成する必要はありません。

于 2012-06-26T16:36:04.453 に答える