之前只是知道尽量用强引用,不要用弱引用,因为弱引用会被垃圾回收. 对于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,让我们来一边享受引用,一边学习吧。
源码:
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); } } }
» 本文链接地址:https://www.litefeel.com/weak-reference-addeventlistener/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
This post was last modified on 2019 年 03 月 04 日 01:02
View Comments (5)
@as3
现在OK了,不报错了
@as3
因为调用了却没有执行,所以是被回收了
饿。。当时知道。。都报IOError了。。呵呵,我自己重新编译的。。弱引用进度一直是0,还有你怎么确定垃圾回收了?
@as3
因为加载的文件没有了,所以你自己换个地址,然后再重新编译下测试吧
怎么测试。。弱引用进度一直为0。。?= =