Actionscript 3 如何使闭包外部范围引用变弱。或任何其他解决方法
假设1。我有一个名为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
实验的实用类。它有助于监听选定精灵上的帧事件。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(…)
。