这会导致内存泄漏吗?
var mc:MovieClip ; //<<<<<<< OUTSIDE LOOP
for ( var i=0 ; i< 1000 ; i++)
{
mc = new MovieClip() ;
mc.addEventListener( MouseEvent.CLICK , onClick) ;
}
那怎么样?
for ( var i=0 ; i< 1000 ; i++)
{
var mc:MovieClip ; //<<<<<<< INSIDE LOOP
mc = new MovieClip() ;
mc.addEventListener( MouseEvent.CLICK , onClick) ;
}
“removeEventListener”在上面的任何代码中都没有使用,所以我认为两者都会导致内存泄漏。
你的1000个动画片段将引用你的onClick功能。不是相反。
因此,如果你质疑你的1000个动画片段是否会获得GCed:如果他们没有任何其他参考,他们最终会。
另一方面,影片剪辑中对onClick函数的引用将使该影片保持活动状态(以及它可能属于的对象)。如果这些MC有任何其他参考,将使他们活着。
以下代码:
mc.addEventListener(MouseEvent.CLICK , function(ev:Event):void{ trace("I am only a poor anonymous function"); }, false, 0, true);
很快就会有你的监听器功能GCed,因为它没有任何强大的参考。
设置 将useWeakReference 如果您向舞台添加Eventlistener,则为true可能非常相关
stage.addEventListener(MouseEvent.CLICK, someObjectBelowIntheDisplayList.listenerFunction);
上面的代码将使Object与您的侦听器函数保持活动状态,即使它没有其他引用也是如此。
someObjectBelowIntheDisplayList.addEventListener(MouseEvent.CLICK, stage.onClick)
上面的代码不会保留你的 someObjectBelowIntheDisplayList 活。它有一个阶段的参考,但阶段没有得到参考 someObjectBelowIntheDisplayList
编辑:请尝试以下代码:
import flash.display.MovieClip;
import flash.events.Event;
var mc:MovieClip ; //<<<<<<< OUTSIDE LOOP
function enterframe(ev:Event):void
{
for ( var i=0 ; i< 1000 ; i++)
{
mc = new MovieClip() ;
mc.onClick = function(ev:Event){};
// Use one of the following lines, comment out the other one
//mc.addEventListener( MouseEvent.CLICK , onClick) ; // no memory leak
stage.addEventListener(MouseEvent.CLICK, mc.onClick); // memory will rise up and up
}
}
this.addEventListener(Event.ENTER_FRAME, enterframe);
function onClick(ev:Event):void
{
}
这段代码清楚地支持我所说的:使用mc.addEventListener会 不 获得内存消耗。它将在我的系统上保持大约20MB。
当使用具有stage.addEventListener的行并使用mc.onClick作为侦听器函数时,内存消耗将每帧上升。
更新,正确答案
我原来的答案是错的,我真诚地道歉。我将保留所有居高临下的评论和信息,以便羞耻可能永远提醒我永远不要相信任何Adobe再次说的话。目前的文档现在说:
“如果您不再需要事件侦听器,请通过调用removeEventListener()将其删除,否则可能会导致内存问题。事件侦听器不会自动从内存中删除,因为垃圾收集器不会删除侦听器 只要调度对象存在 (除非useWeakReference参数设置为true)。“
注意事件监听器是垃圾收集天气有弱参考或者没有,只要首先删除调度对象。因此,在这两种情况下,它们都不会导致内存泄漏。我要求OP取消检查我的答案是否正确,并给@Malyngo提供信用/正确答案+ upvotes。
原始(错误)答案和(错误)信息跟随
两者都会。绑定事件侦听器会创建对原始对象的强引用,因此垃圾收集器不会清除它。您需要显式删除事件侦听器或将它们指定为弱引用,这应该是addEventListener的参数之一。
对于那些认为听众不会阻止其他对象被垃圾收集的人
http://gingerbinger.com/2010/07/actionscript-3-0-events-the-myth-of-useweakreference/
文章摘要:
“想象一下我们的玩家死了,我们希望他被清理干净。但是,事件监听器会创建从舞台到玩家的参考。舞台是最顶层的显示对象,并且始终可以访问。因此,当标记扫描时进程运行时,即使我们已清除所有其他引用并将其从显示列表中删除,此事件侦听器也允许垃圾收集器从舞台跳转到我们的播放器对象。
因此,至少有一种情况是单独的事件监听器(强绑定)可以阻止收集对象。
两个示例都是相同的,因为actionscript基于ecmascript 3,它没有块范围。
编辑:让我更具体一点:没有块范围,但ActionScript中有功能范围。
与内存泄漏一样,对象将保留在内存中。