【问题标题】:AS3: Reusing URLLoader, URLRequest, and URLVariables instancesAS3:重用 URLLoader、URLRequest 和 URLVariables 实例
【发布时间】:2018-08-18 15:11:08
【问题描述】:

我的 Flash 项目大量使用 URLLoader.load 从 Web 服务器加载内容并发布到 php 页面。我应该重复使用我的 URLLoader、URLRequest 和 URLVariables 实例,还是应该每次都创建新实例?如果我每次都要创建新的,是否需要以某种方式处理旧的?

【问题讨论】:

    标签: actionscript-3 optimization actionscript


    【解决方案1】:

    您绝对不应该重用任何与外部操作相关的实例,并且您应该在不需要它们的那一刻彻底处置它们。处理这些对象的垃圾收集器 (GC) 的开销几乎与一旦您的外部操作因共享相同的操作实例而发生冲突时可能陷入的噩梦般的混乱无异。

    URLVariablesURLRequest 不需要任何特殊处理,只需将 null 设置为引用它们的任何变量并确保它们所在的方法分配给局部变量,不产生任何函数闭包。好吧,将 URLRequest.data 设置为 null 以中断此引用。

    URLLoader,另一方面,需要稍微推动一下:

    1. 如果 URLLoader.data 是一个 ByteArray,那么你应该 ByteArray.clear() 它(除非你需要它)。李>
    2. URLLoader.data 设置为 null
    3. 最初订阅所有带有弱引用的错误处理程序(addEventListener 的第五个参数设置为 true)并且不要取消订阅它们。弱键不会影响 GC 的判断,同时保留订阅可能会让您免于偶尔出现 Unhandled Error Event 的情况。
    4. 当然要取消订阅所有非错误处理程序。
    5. 在所有处理程序中,首先检查 Event.target 是否是有效的 URLLoader 实例,以避免处理来自死/已处置的 URLLoader 的事件>.
    6. 调用 URLLoader.close() 以防万一。是的,完成以上所有操作后。

    下面是我用来以简单方式加载内容的类。它建立在我上面列出的相同原则之上。它允许加载文本/二进制数据,还提供了一些针对不稳定网络的证据:如果您知道请求往往会失败有时,您可以将 repeatCount 参数设置为更高的值以提供故障安全加载

    用法

    // Load binary data over unstable network.
    DataFiles.load("data.dat", onData, true, 10);
    
    // Load XML file as text over a stable network or from the local storage.
    DataFiles.load("setup.xml", onSetup);
    
    function onData(source:ByteArray):void
    {
        if (!source)
        {
            // Loading failed. Error case.
        }
        else
        {
            // File is loaded normally.
        }
    }
    
    function onSetup(source:String):void
    {
        try
        {
            var aSetup:XML = new XML(source);
    
            // Process loaded XML normally.
        }
        catch (fail:Error)
        {
            // The source is either null or an invalid XML string.
            // Loading is failed, basically. Error case.
        }
    }
    

    实施

    package simplify
    {
        import flash.events.Event;
        import flash.events.IOErrorEvent;
    
        import flash.net.URLLoader;
        import flash.net.URLRequest;
        import flash.net.URLLoaderDataFormat;
    
        public class DataFiles
        {
            static private var list:Vector.<DataFiles> = new Vector.<DataFiles>;
    
            static public function load(url:String, handler:Function, binary:Boolean = false, repeatCount:int = 1):void
            {
                var aLoader:DataFiles = new DataFiles;
    
                aLoader.url = url;
                aLoader.binary = binary;
                aLoader.handler = handler;
                aLoader.repeatCount = repeatCount;
    
                list.push(aLoader);
                aLoader.start();
            }
    
            private var url:String;
            private var binary:Boolean;
            private var handler:Function;
    
            private var loader:URLLoader;
    
            private var repeatCount:int;
    
            private function start():void
            {
                loader = new URLLoader;
    
                if (binary) loader.dataFormat = URLLoaderDataFormat.BINARY;
    
                loader.addEventListener(Event.COMPLETE, onComplete);
                loader.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
    
                loader.load(new URLRequest(url));
            }
    
            private function destroyLoader():void
            {
                if (!loader) return;
    
                loader.removeEventListener(Event.COMPLETE, onComplete);
    
                var aDead:Loader = loader;
    
                loader = null;
    
                aDead.data = null;
                aDead.close();
            }
    
            private function onComplete(e:Event):void
            {
                if (e.target != loader) return;
    
                var aResult:* = loader.data;
                var aHandler:Function = handler;
    
                destroy();
                destroyLoader();
                aHandler(aResult);
            }
    
            private function onError(e:IOErrorEvent):void
            {
                if (e.target != loader) return;
    
                destroyLoader();
                repeatCount--;
    
                if (repeatCount >= 0)
                {
                    start();
                }
                else
                {
                    var aHandler:Function = handler;
    
                    destroy();
                    aHandler(null);
                }
            }
    
            private function destroy():void
            {
                var anIndex:int = list.indexOf(this);
                if (anIndex > -1) list.splice(anIndex, 1);
    
                handler = null;
                url = null;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      相关资源
      最近更新 更多