我需要在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实例作为索引吗?那会有任何奇怪的依赖吗?
干杯
答案 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));
}