弱引用 addEventListener

发表评论 阅读评论

之前只是知道尽量用强引用,不要用弱引用,因为弱引用会被垃圾回收. 对于flash.utils.Dictionary倒是没有什么疑问.但EventDispatcher.addEventListener就不明白具体是侦听器被回收了,还是侦听者被回收了。
昨天有看了一些文章,又想起这个问题,就想要理解透彻,于是又仔细看了下API文档.

Class-level member functions are not subject to garbage collection, so you can set useWeakReference to true for class-level member functions without subjecting them to garbage collection. If you set useWeakReference to true for a listener that is a nested inner function, the function will be garbge-collected and no longer persistent. If you create references to the inner function (save it in another variable) then it is not garbage-collected and stays persistent.

原来这里的弱引用是对侦听器的(侦听器函数),跟侦听者没有关系. 为了验证这个观点,我做了个小Demo。
OK,让我们来一边享受引用,一边学习吧。

这是弱引用的测试demo,如果你看不到这个flash,请到文章页面查看!

源码:

package
{
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.media.Sound;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.system.System;
    import flash.text.TextField;
    import flash.utils.Dictionary;

    /**
     * 弱引用错误用法示例
     * @author lite3
     */
    [SWF(width=300, height=100, backgroundColor=0xC7EDCC)]
    public class WeakReferenceExample extends Sprite 
    {
        private var weakTxt:TextField;
        private var strongTxt:TextField;
        private var sound:Sound = new Sound();
        private var arr:Array = [];
        public function WeakReferenceExample():void 
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            initUI();
            sound.load(new URLRequest("http://lite3.googlecode.com/files/WZ_woMenDouShiHaoHaiZi.mp3?" + Math.random()));
            sound.play();
            sound.addEventListener(ProgressEvent.PROGRESS, getHandler(true), false, 0, true);
            sound.addEventListener(ProgressEvent.PROGRESS, getHandler(false), false, 0, false);
            sound.addEventListener(Event.COMPLETE, completeHandler);

            // 加快垃圾回收
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        private function getHandler(isWeak:Boolean):Function
        {
            return isWeak ? weakProgressHandler : strongProgressHandler;
            function weakProgressHandler(e:ProgressEvent):void
            {
                weakTxt.text = "弱引用:加载进度:" + ((e.bytesLoaded / e.bytesTotal * 100) >> 0) + "%";
            }
            function strongProgressHandler(e:ProgressEvent):void
            {
                strongTxt.text = "强引用:加载进度:" + ((e.bytesLoaded / e.bytesTotal * 100) >> 0) + "%";
            }
        }

        private function enterFrameHandler(e:Event):void 
        {
            if (System.totalMemory >= 500 * 1024 * 1024)
            {
                removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }else
            {
                arr.push(new BitmapData(500, 500, true));
            }
        }
        private function completeHandler(e:Event):void
        {
            removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            strongTxt.text = "加载已完成!";
        }

        private function initUI():void
        {
            // 说明文本
            var txt:TextField = new TextField();
            txt.text = "测试弱引用!\nprogressHandler使用若引用.\ncompleteHandler使用强引用.";
            txt.width = stage.stageWidth;
            txt.height = txt.textHeight + 4;
            txt.mouseEnabled = false;
            addChild(txt);

            // 弱引用文本
            weakTxt = new TextField();
            weakTxt.width = stage.stageWidth;
            weakTxt.height = 20;
            weakTxt.text = "弱引用:加载进度:0%";
            weakTxt.y = txt.height;
            addChild(weakTxt);

            // 强引用文本
            strongTxt = new TextField();
            strongTxt.width = stage.stageWidth;
            strongTxt.height = 20;
            strongTxt.text = "强引用:加载进度:0%";
            strongTxt.y = txt.height + weakTxt.height;
            addChild(strongTxt);
        }
    }
}

  1. lite3 | | #1

    @as3
    现在OK了,不报错了

  2. lite3 | | #2

    @as3
    因为调用了却没有执行,所以是被回收了

  3. as3 | #3

    饿。。当时知道。。都报IOError了。。呵呵,我自己重新编译的。。弱引用进度一直是0,还有你怎么确定垃圾回收了?

  4. lite3 | | #4

    @as3
    因为加载的文件没有了,所以你自己换个地址,然后再重新编译下测试吧

  5. as3 | #5

    怎么测试。。弱引用进度一直为0。。?= =

  1. Pingback: 1pestilent
回到顶部