2

问题一:

在以下示例中,我向 foundMic 添加了一个侦听器。我的问题是如果我重新运行 foobar.initMic(); 要重新初始化麦克风,我最终会在内存中浮动一个死事件侦听器,它会被垃圾收集器拾取吗?调用 .getMicrophone() 只是将相同的资源重新附加到 foundMic 还是破坏旧的 foundMic 并在内存中创建一个新的 foundMic 实例。

就像它完全相同的 foundMic 一样,添加事件侦听器将静默失败并且不会创建第二个侦听器。但是,如果 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

问题二:

基于问题一,如果我在添加侦听器之前添加了一个删除侦听器,那实际上是否在第二次运行时删除了该方法第一次运行时创建的侦听器?或者 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

foundMic 将被分配一个新值,该值是对麦克风的引用 - 不应进行垃圾收集。

垃圾收集器应该启动的情况是这样的:

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

在这种情况下,您创建了 5 个新的 Sprite 对象,但最终只分配了一个给 someVar 变量 - 其他 4 个应该在某个时候被垃圾收集,因为它们没有被任何变量引用。

至于问题二,您的代码应该在您第一次调用 initMic() 时给您一个错误,因为那时还没有 onMicStatusEvent 侦听器。在尝试删除事件侦听器之前,首先测试它是否存在:

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

此代码将始终首先删除事件侦听器(如果存在),然后添加新的事件侦听器。但是,在这种情况下,我看不出有任何原因,因为 addEventListener 本身应该可以正常工作 - 多个调用都在同一个对象上,所以无论你调用多少次 initMic() 你应该只有一个事件侦听器正在运行 - 无需手动删除侦听器然后重新创建。

于 2012-06-26T16:36:04.453 回答
0

这是事件侦听器发生的情况。someObject.addEventListener('someEvent', someFunction)someObject参考someFunction。由于作用域在 ActionScript 中的工作方式,该函数可以访问创建它的代码作用域中的所有内容。因此,在您调用 之前removeEventListener,只要在内存中,函数存在的实例就会保存在内存someObject中。

但是,在您的情况下,没有实例,因为通过使用静态函数,您的侦听器将从第FooBar一次引用您的 Class 到您的 swf 从计算机内存中取出。

在添加侦听器之前删除侦听器没有任何净效果,因为它是完全相同的函数被传递给完全相同的对象,它不会调用您的函数两次。

有关事件侦听器如何详细工作的更多信息,请查看此博客文章

于 2012-06-26T23:11:09.037 回答