之前只是知道尽量用强引用,不要用弱引用,因为弱引用会被垃圾回收. 对于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。。?= =