AS3将函数作为参数传递会产生内存泄漏

God*_*her 8 flash memory-leaks function-pointers actionscript-3

我有一个函数,它将另一个函数作为参数.像这样的东西:

public function onHits(target : Shape, callback : Function) : void
Run Code Online (Sandbox Code Playgroud)

我通过传递一个成员函数作为参数来使用它,只要传递的目标命中某个东西就应该调用它.该函数被一次调用多次.所以它用于做:

//code...
CollisionManager.onHits(myShape, onHitCB);
//code...
Run Code Online (Sandbox Code Playgroud)

点击功能:

public function onHitCB(hitObject : *) : void 
{
    //removed all code to test this problem
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我有内存泄漏.我已经将问题与onHits方法隔离开来,并已注释掉其他所有内容.onHits是一个空方法,里面没有代码,onHitCB也是空的.如果我注释掉对onHits的调用,则没有内存泄漏,如果我传递null而不是onHitCB,则没有内存泄漏.

因此,当我将HitCB作为参数传递给问题时,显然也是如此.所以我认为这可能是因为Flash分配了一些内存来创建Function指针并且不释放它但是我在调​​试模式中每一帧调用System.gc()并且泄漏仍然存在.这意味着这可能是SDK中的错误,或者我没有做正确的事情.

通过保持一个指向我在对象的构造函数中指定的函数的变量,我找到了一个奇怪的解决方法:

private var func : Function;

public function MyObject() 
{
    func = onHitCB;
}
Run Code Online (Sandbox Code Playgroud)

即使我仍然将HitCB作为参数传递,这也将清除内存泄漏.那么这意味着获取onHitCB不是"getter"函数,而是导致内存泄漏的其他因素?

我很困惑.这怎么会导致内存泄漏:

public function MyObject() 
{
}

public function update() : void
{
    CollisionManager.onHits(myShape, onHitCB);//empty function
}

public function onHitCB(hitObject : *) : void 
{
    //removed all code to test this problem
}
Run Code Online (Sandbox Code Playgroud)

但不是吗?:

private var func : Function;
public function MyObject() 
{
    func = onHitCB;
}

public function update() : void
{
    CollisionManager.onHits(myShape, onHitCB);//empty function
}

public function onHitCB(hitObject : *) : void 
{
    //removed all code to test this problem
}
Run Code Online (Sandbox Code Playgroud)

有没有办法不必这样做?

kap*_*pex 5

将方法作为参数传递时,会自动创建绑定方法.绑定方法确保this关键字始终引用定义方法的对象或类. 资源

这听起来像创建对方法的引用不是使用简单的getter.生成一个新的方法闭包对象.所以你的假设是正确的.

我想知道为什么没有为每个实例缓存引用,为什么它们不是垃圾收集.最好避免创建多个引用.仅仅引用一次方法就像我在多个地方使用该方法时所做的那样,所以大多数时候我不会称之为解决方法,而是一种良好的干练习.在您的示例中,它当然是有道理的,假设方法引用将使用简单的getter.