Created
April 1, 2013 10:50
-
-
Save lynxerzhang/5284263 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.display.DisplayObject; | |
import flash.display.DisplayObjectContainer; | |
import flash.events.Event; | |
import flash.events.IEventDispatcher; | |
import flash.utils.Dictionary; | |
/** | |
* | |
* 绑定事件监听的依据为指定根容器是否有显示对象移除, 如有移除, 则以此显示对象配置的事件监听一并清除 | |
* | |
* TODO LIST | |
* 1.未考虑是否需要显示对象未添加至舞台时, 屏蔽事件回调 | |
* 2.监测显示对象以强引用存入Dictionary, 是否需要以弱引用存入Dictionary, 即无任何引用时, | |
* 销毁改显示对象的同时, 清除所有对应监听 | |
* @see http://code.google.com/p/asphalt2/ asphalt2.util.EventUtil | |
*/ | |
public class LifeCircleStats | |
{ | |
/** | |
* 设置指定显示对象主容器 | |
* @param container | |
*/ | |
public function LifeCircleStats(container:DisplayObjectContainer){ | |
root = container; | |
root.addEventListener(Event.REMOVED, removedChildHandler);//handle by target phase or bubble phase | |
} | |
/** | |
* 当被移除的显示对象为指定根容器的子级或即为根容器时, 移除对应该显示对象配置的事件监听函数 | |
* @param evt | |
*/ | |
private function removedChildHandler(evt:Event):void{ | |
var target:DisplayObject = DisplayObject(evt.target); | |
for(var item:* in check){ | |
if(checkParent(item, target)){ | |
check[item].forEach(forEachNode); | |
check[item] = undefined; | |
delete check[item]; | |
} | |
} | |
} | |
private function forEachNode(node:Nd, ...args):void{ | |
node.remove(); | |
} | |
private var root:DisplayObjectContainer; | |
private const check:Dictionary = new Dictionary(false); | |
/** | |
* 添加监听, 并指定监测显示对象 | |
* @param dispatcher | |
* @param type | |
* @param listener | |
* @param lifeCircleDisplay | |
*/ | |
public function create(dispatcher:IEventDispatcher, type:String, listener:Function, lifeCircleDisplay:DisplayObject):void{ | |
dispatcher.addEventListener(type, listener); | |
if(!check[lifeCircleDisplay]){ | |
check[lifeCircleDisplay] = []; | |
} | |
check[lifeCircleDisplay].push(new Nd(dispatcher, type, listener, lifeCircleDisplay)); | |
} | |
/** | |
* 移除指定显示对象监听函数 | |
* @param dispatcher | |
* @param type | |
* @param listener | |
*/ | |
public function remove(dispatcher:IEventDispatcher, type:String, listener:Function):void{ | |
var k:Array, len:int | |
for(var item:* in check){ | |
k = check[item]; | |
len = k.length; | |
while(--len > -1){ | |
if(k[len].dispatcher == dispatcher && k[len].type == type && k[len].listener == listener){ | |
k.splice(len, 1)[0].remove(); | |
} | |
} | |
if(k.length == 0){ | |
check[item] = undefined; | |
delete check[item]; | |
} | |
} | |
} | |
/** | |
* 移除指定监测显示对象为键的所有事件监听函数方法 | |
* @param lifeCircleDisplay | |
*/ | |
public function clear(lifeCircleDisplay:DisplayObject):void{ | |
if(lifeCircleDisplay in check){ | |
var k:Array = check[lifeCircleDisplay]; | |
var len:int = k.length; | |
while(--len > -1){ | |
k[len].remove(); | |
} | |
check[lifeCircleDisplay] = undefined; | |
delete check[lifeCircleDisplay]; | |
} | |
} | |
} | |
} | |
import flash.events.Event; | |
import flash.events.IEventDispatcher; | |
/** | |
* 避免大规模使用动态函数对象, 其所造成的内存消耗很大, 由此创建普通对象存储对应函数引用 | |
* 如下使用内置的getSize获取创建对象的字节数可发现 | |
* var s:Sprite = new Sprite(); | |
* trace(getSize(function():void{})); //654 | |
* trace(getSize(s.addEventListener)); //256 | |
*/ | |
internal class Nd{ | |
public var listener:Function; | |
public var dispatcher:IEventDispatcher; | |
public var type:String; | |
public var display:DisplayObject; | |
public function Nd(d:IEventDispatcher, type:String, listener:Function, dis:DisplayObject):void{ | |
this.dispatcher = d; | |
this.type = type; | |
this.listener = listener; | |
this.display = dis; | |
} | |
public function remove():void{ | |
this.dispatcher.removeEventListener(this.type, this.listener); | |
} | |
} | |
import flash.display.DisplayObject; | |
import flash.display.DisplayObjectContainer; | |
/** | |
* 检查是否存在指定的父子级显示层级关系 | |
* @param detectDisplay | |
* @param detectParent | |
* @return | |
*/ | |
internal function checkParent(detectDisplay:DisplayObject, detectParent:DisplayObject):Boolean{ | |
if(detectDisplay == detectParent){ | |
return true; | |
} | |
if(detectParent is DisplayObjectContainer){ | |
if(DisplayObjectContainer(detectParent).contains(detectDisplay)){ | |
return true; | |
} | |
} | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment