在过去的一个月左右的时间里,我一直在教自己动作脚本3,最近遇到了一个问题,一个物体在我认为被删除之后仍在继续做事.我发现问题是由使用默认值useWeakReference = false的事件监听器引起的,我想知道为什么这是默认值.不使用弱引用有什么好处?为什么这是默认的?在我看来,一般来说你想要使用弱引用,所以我必须遗漏一些东西.
谢谢,-Ted
关键是,弱引用很昂贵......它们都比较慢并占用更多空间......这里有一些基准代码:
package { //{ region imports import flash.display.Sprite; import flash.events.Event; import flash.events.EventDispatcher; import flash.system.System; import flash.utils.*; //} endregion public class Main extends Sprite { public function Main():void { switch (0) { case 0: this.benchmarkDispatchers(false); break; case 1: this.benchmarkDispatchers(true); break; case 2: this.benchmarkDictionaries(false); break; case 3: this.benchmarkDictionaries(true); break; } } private function benchmarkDictionaries(weakKeys:Boolean, size:uint = 1000000):void { var a:Array = []; for (var i:int = 0; i < size; i++) a.push( { "foo":i } ); var d:Dictionary = new Dictionary(weakKeys); var start:int = getTimer(); var mem0:int = System.totalMemory; for (var j:int = 0; j < size; j++) d[a[j]] = j; trace("adding "+size+" keys took "+(getTimer()-start)+" msecs and "+(System.totalMemory-mem0)+" B of memory with weakKeys == "+weakKeys); } private function benchmarkDispatchers(weakRef:Boolean, size:uint = 100000):void { var a:Array = []; var f:Function = function (i:*):Function { return function ():void { i; } } for (var i:int = 0; i < size; i++) a.push( f(i) ); var e:EventDispatcher = new EventDispatcher(); var start:int = getTimer(); var mem0:uint = System.totalMemory; for (var j:int = 0; j < size; j++) e.addEventListener("foo", a[j], false, 0, weakRef); trace("adding " + size + " event handlers took " + (getTimer() - start) + " msecs and " + (System.totalMemory - mem0) + " B of memory with weakKeys == " + weakRef); } } }
这就是我在我的机器上得到的东西:
adding 100000 event handlers took 679 msecs and 6922240 B of memory with weakKeys == false adding 100000 event handlers took 1348 msecs and 13606912 B of memory with weakKeys == true adding 1000000 keys took 283 msecs and 16781312 B of memory with weakKeys == false adding 1000000 keys took 906 msecs and 42164224 B of memory with weakKeys == true
结果是字典一点更激烈,最有可能因为不涉及ActionScript调用,关于时间,因为在事件处理程序登记一些存储开销,减轻所需的内存之间的区别(你可以看到,这是69字节/处理器和16字节/键,比较弱引用时)...
所以是的,它是关于性能的...使用弱引用并不是关于很酷的事实,你不必删除监听器以便对象死掉...如果你想拥有一个可扩展的应用程序,你需要自己做这些事情,如果你想让它100%可靠,你就不能希望GC能够完成你的工作,但是你需要自己做清理...而且,如果你有一个好的你的应用程序中的层次结构,你可能不会经常遇到这个问题 ......从某种意义上说,如果你不想花时间做适当的对象清理,这是一种奢侈,因为没有弱点就无法解决的问题参考是罕见的...它应该在它提供真正的优势时使用,而不仅仅是出于懒惰...我认为这就是为什么它默认是假的...
希望有帮助......;)
格尔茨
back2dos