任意数量的匿名Loader犯有个人数据?

时间:2009-05-12 15:28:25

标签: flex actionscript-3 actionscript event-handling anonymous-function

我需要在AIR应用程序中加载任意数量的文件。

我想迭代一个File对象数组,为每个File.url创建并启动Loaders。

当它们完成时(事件COMPLETED或IOErrorEvent.IO_ERROR),我想把它们的数据填入某处。如果他们失败了,我想做一个例外报告。我找不到任何方法从事件监听器引用File对象(当然不是IO_ERROR)

最好的方法是为每个具有“硬编码”文件信息的Launcher创建单独的事件处理程序。至少,我可以将函数本身用作Dictionary的索引:

foo(fileToLoad : File) : void
{
    var theCompletedHandler : Function = 
    {
        var theFile : File = completedHandlerLookup[?????? this function ?????];
        var theData : ImageData = 
            new ImageData(theFile.url, (_loader.content as Bitmap).bitmapData);

        // do something with the data

        delete completedHandlerLookup[?????? this function ?????];
        delete errorHandlerLookup.findByValue(theFile); // [sic]
    }

    var theErrorHandler : Function = 
    {
        var theFile : File = errorHandlerLookup[?????? this function ?????];

        // report the error

        delete errorHandlerLookup[?????? this function ?????];
        delete completedHandlerLookup.findByValue(theFile); // [sic]
    }

    completedHandlerLookup[theCompletedHandler] = theCompletedHandler;
    errorHandlerLookup[theCompletedHandler] = theErrorHandler;

    var theLoader : Loader = new Loader();
    theLoader.addEventListener(Event.COMPLETE, theCompletedHandler); 
    theLoader.addEventListener(IOErrorEvent.IO_ERROR, theErrorHandler); 
    theLoader.load(new URLRequest(fileToLoad.url));

我可以使用event.currentTaget并使用Loader实例作为索引吗?那会有任何奇怪的依赖吗?

干杯

1 个答案:

答案 0 :(得分:2)

您可以使用event.currentTarget作为索引查找,只要清除所有引用就应该没有问题。但请注意,loader事件侦听器被添加到loader.contentLoaderInfo,因此可以通过e.currentTarget.loader访问loader。

另外值得一提的是,对这种情况采用更简单的方法是构建基于队列的系统,因此它一次只能加载一个文件。例如,将所有文件存储在数组中。然后在COMPLETE或IO_ERROR上,您将处理当前文件,然后启动下一个文件。这将是更好的资源明智(只有一个加载器),并避免垃圾收集问题。

我也有点好奇为什么你是匿名函数?从垃圾收集的角度来看,它们并不是很好,实际上使这种情况复杂化。这是一项要求吗?

编辑:这是一个基于队列的系统如何解决这个问题的粗略(不完整)示例。

var loader:Loader;
var queue:Array;

function addFile(file:File):void
{
     queue.push(file);
}

function handleLoadedAsset(e:Event):void 
{
    var currentFile:File= queue[0];
    //do whatever
    stepQueueForward();
}

function handleFailedAssetLoad(e:IOErrorEvent):void 
{
    var currentFile:File = queue[0];
    //clean up
    stepQueueForward();
}

function stepQueueForward():void
{
    queue.splice(0, 1);
    var nextFile:File = queue[0];
    loader.load(new URLRequest(nextFile.url));
}