Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local Timer Object Event Handler

I have the following code in a class function :

public function foo():void
{
    var timer:Timer = new Timer(10000,1);
    timer.addEventListener(TimerEvent.TIMER_COMPLETE,onTimerComplete);
    timer.start();
}

public function onTimerComplete(e:TimerEvent):void
{
  // do stuff
}

The above code works most of the time but my concern is what happens if timer gets garbage collected? Is it possible that onTimerComplete will never fire because there are no other references to timer?

I know timer has an internal list of handlers but that won't keep it from being GC'ed.

like image 580
Barış Uşaklı Avatar asked Nov 13 '22 23:11

Barış Uşaklı


1 Answers

There are some references on the web to running timers never being garbage collected, e.g.:

Just to be clear: even if you have no references to a Timer, as long as the timer is running, it will not be Garbage Collected (think of it as if the runtime was keeping a reference to running timers).

by Arno Gourdol on the Adobe AIR Team

but I haven't been able to find an authoritative source.

Probably best to not rely on this special behavior and instead make timer a class-level variable, though.

Answers suggesting that event listeners are keeping the timer from being garbage collected are incorrect. The reference is from the timer to the listener function (onTimerComplete), so if the timer is reachable then the listener function won't be garbage collected, but not vice versa. This is easily tested:

<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="application1_creationCompleteHandler(event)">

<fx:Script>
    <![CDATA[
private var _gcTimer:Timer;

protected function application1_creationCompleteHandler(event:FlexEvent):void {
    var timer:Timer = new Timer(30, 4);
    timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
    
    var sprite:Sprite = new Sprite();
    sprite.addEventListener(Event.ENTER_FRAME, onSprite, false, 0, true);
    
    _gcTimer = new Timer(59, 1);
    _gcTimer.addEventListener(TimerEvent.TIMER, garbageCollect);

    timer.start();
    _gcTimer.start();
}

private function onTimer(event:TimerEvent):void {
    trace("timer");
}

private function onSprite(event:Event):void {
    trace("sprite");
}
]]>
</fx:Script>
</s:Application>

Output:

sprite
timer
sprite
timer
Collecting garbage
timer
timer

like image 161
blahdiblah Avatar answered Dec 29 '22 14:12

blahdiblah