Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 如何使闭包外部范围引用变弱。或任何其他解决方法_Actionscript 3_Apache Flex - Fatal编程技术网

Actionscript 3 如何使闭包外部范围引用变弱。或任何其他解决方法

Actionscript 3 如何使闭包外部范围引用变弱。或任何其他解决方法,actionscript-3,apache-flex,Actionscript 3,Apache Flex,假设1。我有一个名为实验的实用类。它有助于监听选定精灵上的帧事件。API如下所示:experience.listenterframe(mySprite,onEnterFrameHandler) 假设2。我希望我的实验.listenterframe类允许使用匿名处理程序。我还希望它能够防止内存泄漏(没有任何cleanUp()方法),即对mySprite的引用应该很弱 代码如下: package { import flash.display.Sprite; import flash.events.E

假设1。我有一个名为
实验的实用类。它有助于监听选定精灵上的帧事件。API如下所示:
experience.listenterframe(mySprite,onEnterFrameHandler)

假设2。我希望我的
实验.listenterframe
类允许使用匿名处理程序。我还希望它能够防止内存泄漏(没有任何
cleanUp()
方法),即对mySprite的引用应该很弱

代码如下:

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.system.System;
import flash.utils.Dictionary;
import flash.utils.setTimeout;

public class Experiment extends Sprite
{
    public function Experiment()
    {
        new MemoryLeakTest();
        new NoMemoryLeakTest();
        setTimeout(System.gc, 100);
    }

    private static var dict:Dictionary = new Dictionary(true);

    private static function listener(event:Event)
    {
        dict[event.currentTarget]();
    };

    public static function listenEnterFrame(dispatcher:Sprite, callback:Function):void
    {
        dict[dispatcher] = callback;
        dispatcher.addEventListener(Event.ENTER_FRAME, listener, false, 0, true);
    }
}
}

import flash.display.Sprite;

internal class MemoryLeakTest extends Sprite
{
    function MemoryLeakTest():void
    {
        Experiment.listenEnterFrame(this, function () {
            trace("Memory leak");
        });
    }
}

internal class NoMemoryLeakTest
{
    function NoMemoryLeakTest():void
    {
        Experiment.listenEnterFrame(new Sprite(), function () {
            trace("No Memory leak");
        });
    }
}
在上面的示例中,MemoryLeakTest实例永远不会被删除-永远跟踪“内存泄漏”

我对此的解释是,在
MemoryLeakTest
中创建的
callback
闭包保留了对外部范围的引用,即
MemoryLeakTest
实例本身。由于此引用,
MemoryLeakTest
实例不能被垃圾收集


您知道任何解决方法吗,这样我就可以在我的实用工具方法中使用匿名回调,而不必担心内存释放问题?

AS3中有一个已知的字典错误。不再存储对函数/方法的引用,而是存储对闭包对象的引用

这意味着,如果希望将函数引用存储为字典中的键,那么如果字典使用弱键,它将立即标记为GC,因为字典引用的是闭包对象,而不是函数本身

这也意味着,如果您试图将函数引用作为值存储在字典中,那么只要字典中保存了闭包对象,闭包对象引用的实例就不会被GC调用。(字典有弱键而不是值!)
这正是这里发生的事情

AS3中有一个已知的字典错误。不再存储对函数/方法的引用,而是存储对闭包对象的引用

这意味着,如果希望将函数引用存储为字典中的键,那么如果字典使用弱键,它将立即标记为GC,因为字典引用的是闭包对象,而不是函数本身

这也意味着,如果您试图将函数引用作为值存储在字典中,那么只要字典中保存了闭包对象,闭包对象引用的实例就不会被GC调用。(字典有弱键而不是值!)
这正是这里发生的事情

创建类的新实例而不将这些实例存储在变量中是非常罕见的;就像在构造函数中一样。不过,我不确定这是否与内存问题有关。我有一个可读性最好的例子。实例可以很容易地存储在变量中,并在校准System.gc()之前将其置零。没关系,你可能想用as3信号,因为它已经处理了很多。您可能还想考虑EngyFrand是一个广播事件,这意味着对于该事件来说,侦听一个特定的实例是没有好处的。EntulyFrand只是为了演示的目的,真正的用法是使用这样的实用方法:<代码> BIN(分派器,属性,变更处理程序)< /> >,例如:代码>绑定(这个,“文本””。,函数(){trace(“text changed”)})。AS3信号在这种情况下有何帮助?创建类的新实例而不将这些实例存储在变量中是非常罕见的;就像在构造函数中一样。不过,我不确定这是否与内存问题有关。我有一个可读性最好的例子。实例可以很容易地存储在变量中,并在校准System.gc()之前将其置零。没关系,你可能想用as3信号,因为它已经处理了很多。您可能还想考虑EngyFrand是一个广播事件,这意味着对于该事件来说,侦听一个特定的实例是没有好处的。EntulyFrand只是为了演示的目的,真正的用法是使用这样的实用方法:<代码> BIN(分派器,属性,变更处理程序)< /> >,例如:代码>绑定(这个,“文本””。,函数(){trace(“text changed”)})。AS3信号在这种情况下有什么帮助?谢谢!我就是这么想的。但问题是,如何绕过这个特定的用例?因此,我可以创建类似于
bind(dispatcher、property、onChangeListener)
的实用程序,用于匿名函数,而无需担心
unbind(…)
。谢谢!我就是这么想的。但问题是,如何绕过这个特定的用例?因此,我可以创建类似于
bind(dispatcher、property、onChangeListener)
的实用程序,与匿名函数一起使用,而无需担心
unbind(…)