AS3:重用 URLLoader、URLRequest 和 URLVariables 实例

Posted

技术标签:

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

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

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

以上是关于AS3:重用 URLLoader、URLRequest 和 URLVariables 实例的主要内容,如果未能解决你的问题,请参考以下文章

ActionScript 3 AS3:使用URLLoader进行文本和XML

(swf as3 XML URLLoader) 在 flex 中不起作用

as3中xml文件的加载和读取

将URLLoader与外部URL一起使用时出现“错误#2048:安全沙箱违规”

AS3加载外部文本文件

使用 as3 加载 XML 文件