how does flash handle garbage collection when it c

2019-08-18 05:12发布

问题:

Just curious, If i nest a movieclip inside of another movieclip, and the nested movieclip is attached to a custom class. And that custom class has a Event.ENTER_FRAME listener. when I destroy the container movieclip, will flash get rid of the event listeners inside of nested movieclip's custom class ?

May seem like a silly question but flash has a tendency of not killing listeners along with the movieclip itself once it is removed from the stage(this is if your apply the movieclip via addChild). and its a hastle when things get too complex. My solution was to create a single loop for all my objects. Now ive come to a point where I am probably going to have to nest some movieclips inside of another so the position of the nested movieclip stays relative. the parent movieclip will be rotating and scaling so I rather nest it. But I got to know how flash handles moveiclips that are nested into a parent movieclip and has enter frame listeners. hope this isnt too confusing. thanks!

回答1:

Ok, First of all I was nearly done w/ this answer when my laptop battery completely died so this is round two...

when I destroy the container movieclip, will flash get rid of the event listeners inside of nested movieclip's custom class ?

Your question is a bit confusing, though I think this part of it is the essence of what you are asking so I'll try to answer it based on how I interpret this.

If you have a custom display object and inside that class you add listeners for enter frame or mouse events and add an instance of the custom class to the display list of a another display object, you will need to make sure to remove any listeners and de-reference any external references to the custom class when the parent clip is removed.

One way you can go about this is by adding a listener in your custom class for either the Event.REMOVED or Event.REMOVED_FROM_STAGE events. Inside the handler for either of these events you can remove any listeners and de-reference any objects that might make the garbage collector ignore any otherwise eligible objects. This approach allows you to remove instances of your custom class from the stage using removeChild( myCustomInstance ) and invoking any cleanup in one neat method call.

PsuedoCode:

public class MyCustomDisplayObject 
{
     public function MyCustomDisplayObject()
     {
          addEventListener( Event.ENTER_FRAME, onEnterFrameHandler );
          addEventListener( Event.REMOVED_FROM_STAGE, onRemovedHandler );
     }

     protected function onRemovedHandler( event:Event )
     {
          removeEventListener( Event.ENTER_FRAME, onEnterFrameHandler );
          removeEventListener( Event.REMOVED_FROM_STAGE, onRemovedHandler );
     }
}

You may also want to look into using weakReference set to true in your calls to addEventListener. I don't have much experience w/ weakReference as I prefer to manually remove references.

Here is a short article from Adobe about Flash Player GC:

http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html



回答2:

Your question is wrapped up in a couple of assumptions about movie clips and GC behavior, and I think addressing them will answer your question:

when I destroy the container movieclip, will flash get rid of the event listeners inside of nested movieclip's custom class ?

You can't destroy class objects in AS3, including movieclips. The GC destroys them automatically, but only when there are no more external references to them. Simply removing a movie clip from the stage doesn't "destroy" it in any sense - the object is still there, it keeps all its event listeners, you can still rotate or scale it, or stop it or play it. It's still a normal MC in every sense, it just doesn't happen to be on the stage any more, so it keeps all its events and listeners like any other clip.

flash has a tendency of not killing listeners along with the movieclip itself once it is removed from the stage...

Flash never automatically removes listeners from anything, including movieclips. What you're thinking of is that Flash can garbage collect objects with listeners, and if an object gets GC'ed it will no longer broadcast events. However, the object will only get GCed when there are no more strong references to it, so if you want a movieclip to get destroyed despite having listeners, then you should use weak references when you listen for events, like this:

addEventListener( Events.BLAH, myListener, false, 0, true);

The final argument ("true") specifies weak listeners. But remember, using weak listeners only means that having listeners will not keep the object from being destroyed. In other words, the listener will not count as a reference, but you still have to remove all the other references besides listeners before the object will be GC'ed - simply removing the object from the stage won't cause it to be destroyed unless you have no other references to it.

But I got to know how flash handles moveiclips that are nested into a parent movieclip and has enter frame listeners.

It handles them exactly the same way regardless of whether or not they are nested. The only thing you need to be aware of is, when you add one MC as the child of another, they each keep a reference to each other, so neither one will be a candidate for immediate garbage collection as long as they have a parent-child relationship. If you remove the parent clip from the stage, and destroy all external references to both clips, then they will be candidates for GC, but not until a mark-sweep occurs. Google mark-sweep if you're not familiar with this kind of collection, and all should reasonably clear.

Hope that helps!