垃圾收集的问题(显示列表+动作)垃圾、动作、问题、列表

2023-09-08 11:56:01 作者:为我着迷吧.

如果我添加一个对象,它扩展了一个影片剪辑或雪碧的阶段,我删除对象从舞台上,我需要一个destroy方法,如果:

有没有连接到该对象任何事件监听器 在我添加的显示对象,该对象? (obj.addChild(什么)? - >我需要删除无所谓当我从显示列表中删除对象,或者是说多余的) 在与该对象相关联的任何实例变量 - ?我需要空的 解决方案

如果您删除到父对象的所有引用,这是没有必要删除其孩子的DisplayObject,或空出它的成员变量,假设没有外部参考这些孩子的对象。

Flash使用了标记 - 清除垃圾收集器。要确定哪些对象符合垃圾收集,闪光灯从最上层启动阶段元素,并遍历它找到,这标志着对象,因为它去任何引用。那名未标记的任何对象都是不可达,将有资格进行垃圾回收。

想象一下,一个黑盒子对象。如果您删除该框中的所有引用,这将是符合垃圾收集。现在想象一下,这个黑盒子其实是有它内部的许多子对象。即使可能存在中间父黑匣子和子对象的引用,它不改变的事实,黑盒子本身是不可访问的,因此,所有这些内部的引用并不重要。这些对象将有资格进行垃圾回收。你已经剪断从树的分支,即使该分支本身可能有许多分支和小叉。

移动用户体验设计之列表视图与网格视图 观点 jongde 设计文章 教程分享 站酷 ZCOOL

下面是一个简单的例子:

  VAR OBJ:= MySprite的MySprite的新();
obj.foo =新的Foo();
obj.addChild(新的Sprite());
的addChild(OBJ);
 

我们如何清理 OBJ 及其子组件?所有这一切是必要的:

  removeChild之(OBJ);
OBJ = NULL;
 

现在 OBJ 不可达等等都是它的子组件。他们都是符合垃圾收集。

您应该要小心,如果您有任何外部引用这些子对象,但是:

  VAR OBJ2:雪碧=新的Sprite();
obj.addChild(OBJ2);
OBJ = NULL;
 

尽管我们调零了 OBJ ,我们忘了空出 OBJ2 ,所以它不会被垃圾收集。父 OBJ 对象将不会被垃圾收集,或者说,因为 obj2.parent 引用它。如果 OBJ 是我们的黑盒子,然后我们提到 OBJ2 指向黑盒子里面!

因此​​,它可以很好的做法清洁时一个对象,尤其是在混乱的情况下,目前还不清楚为null,删除的东西。你永远是安全的,如果您删除它们,但你可能最终会写入不必要的code。

如果你想偷看到底是怎么回事,它可以帮助使用Flash Builder,FlashDevelop中,或FDT分析器工具来看看内存的使用情况。您可以使用 System.gc()的调用强制GC在调试模式下运行,如果你想测试这些想法了。

If I add an object that extends a MovieClip or a Sprite to the stage, and I remove that object from the stage, do I need a destroy method if:

There aren't any event listeners attached to that object I added display objects to that object? (obj.addChild(whatever) --> do I need to remove "whatever" when I remove object from the display list or is that redundant?) Any instance variables associated with that object - do I need to null those?

解决方案

If you remove all references to a parent object, it is NOT necessary to remove its children DisplayObjects, or null out its member variables, assuming there are no outside references to these children objects.

Flash uses a "mark-sweep" garbage collector. To determine which objects are eligible for garbage collection, Flash starts from the topmost Stage element and traverses any references that it finds, marking objects as it goes. Any objects that were unmarked are unreachable and will be eligible for garbage collection.

Imagine a black box object. If you remove all references to this box, it will be eligible for garbage collection. Now imagine that this black box actually had many subobjects inside of it. Even though there may be references among the parent black box and the child objects, it doesn't change the fact that the black box itself is inaccessible, so all these "inner" references don't matter. These objects will be eligible for garbage collection. You've snipped the branch from the tree, even though the branch itself may have many offshoots and smaller forks.

Here's a simple example:

var obj:MySprite = new MySprite();
obj.foo = new Foo();
obj.addChild(new Sprite());
addChild(obj);

How do we clean up obj and its subcomponents? All that's necessary is:

removeChild(obj);
obj = null;

Now obj is unreachable, and so are its child components. They are all eligible for garbage collection.

You should be careful if you have any external references to these child objects, though:

var obj2:Sprite = new Sprite();
obj.addChild(obj2);
obj = null;

Even though we nulled out obj, we forgot to null out obj2, so it will not be garbage collected. The parent obj object will not be garbage collected, either, because obj2.parent refers to it. If obj is our black box, then our reference to obj2 is pointing inside of the black box!

Therefore, it can be good practice to null and remove things when cleaning up an object, particularly in confusing situations where it's unclear. You'll always be safe if you remove them, but you might end up writing unnecessary code.

If you want to peek at what is going on, it can be helpful to use the profiler tools in Flash Builder, FlashDevelop, or FDT to take a look at the memory usage. You can use the System.gc() call to force the GC to run in debug mode if you want to test these ideas out.