首页 > AS > 弱引用 addEventListener

弱引用 addEventListener

2010年6月27日 发表评论 阅读评论

之前只是知道尽量用强引用,不要用弱引用,因为弱引用会被垃圾回收.
对于flash.utils.Dictionary倒是没有什么疑问.但EventDispatcher.addEventListener就不明白具体是侦听器被回收了,还是侦听者被回收了 :mrgreen:
昨天有看了一些文章,又想起这个问题,就想要理解透彻,于是又仔细看了下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,让我们来一边享受引用,一边学习吧 :grin:

源码:

package cn.lite3
{
	import cn.lite3.ui.MyContextMenu;
	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 
	{new Dictionary
		private var weakTxt:TextField;
		private var strongTxt:TextField;
		private var sound:Sound = new Sound();
		private var arr:Array = [];
		public function WeakReferenceExample():void 
		{
			this.contextMenu = MyContextMenu.getMyContextNenu();
			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);
		}
	}
}
分类: AS 标签: , ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
有话直说(用户名,邮箱只需填写一次,然后保存到cookie里,第二次将不必重新填写)