ActionScript 3是否需要用于XML的错误事件处理程序?

ActionScript 3是否需要用于XML的错误事件处理程序?

问题描述:

在我正在开发的Flash游戏中,有一些由外部XML文件设置的设置。当我通过Flash IDE运行SWF文件时,它加载正常。如果我运行与投影仪(.exe)相同的文件或独立的SWF文件,则不会加载XML文件。ActionScript 3是否需要用于XML的错误事件处理程序?

我的(意外的)修复是将错误事件侦听器分配给加载器对象。当我再次发布文件时,XML在投影机和独立SWF文件中正确加载。 (我已经证实,注释错误事件处理程序可以恢复错误)。

这里包含的代码块(与无关的代码和功能调用删除):

public function getSettings():void { 
outputBox = getChildByName("output_box") as TextField; 
var xmlLoader:URLLoader = new URLLoader(); 
var xmlData:XML = new XML();     
xmlLoader.addEventListener(Event.COMPLETE, loadXML, false, 0, true); 
xmlLoader.addEventListener(ErrorEvent.ERROR, function (e:Error) 
    { outputBox.appendText(e.message) }); 

try {    
    xmlLoader.load(xmlPath); 
} 
catch(err:Error) { 
    trace(err.message); 
    outputBox.appendText(err.message); 
    checkChances("0"); 
} 

function loadXML(e:Event):void { 

    try { 
     xmlData = new XML(e.target.data); 
     var chances:String = xmlData.chances.text(); 
     var dbURL:String = xmlData.database.text(); 

     trace("Chances are set to: " + chances);      
     trace("Database URL is set to: " + dbURL); 
     outputBox.appendText("Chances are set to: " + chances); 
    } 
    catch(err:Error) {    
     outputBox.appendText(err.message); 
    } 
     checkChances(chances); 
     dbPath = new URLRequest(dbURL); 
}   

}

让我知道,如果你遇到了这一点,或者如果你能提供一些线索照亮可能发生的事情。谢谢!

编辑:

这里是一个不工作的代码。 (我还编辑,做工作,以显示所有我拿出其他位,只是他们可能会影响它的情况下的代码):

public function getSettings():void { 
outputBox = getChildByName("output_box") as TextField; 
var xmlLoader:URLLoader = new URLLoader(); 
var xmlData:XML = new XML();     
xmlLoader.addEventListener(Event.COMPLETE, loadXML, false, 0, true); 
/*xmlLoader.addEventListener(ErrorEvent.ERROR, function (e:Error) 
    { outputBox.appendText(e.message) });*/ 

try {    
    xmlLoader.load(xmlPath); 
} 
catch(err:Error) { 
    trace(err.message); 
    outputBox.appendText(err.message); 
    checkChances("0"); 
} 

function loadXML(e:Event):void { 

    try { 
     xmlData = new XML(e.target.data); 
     var chances:String = xmlData.chances.text(); 
     var dbURL:String = xmlData.database.text(); 

     trace("Chances are set to: " + chances);      
     trace("Database URL is set to: " + dbURL); 
     outputBox.appendText("Chances are set to: " + chances); 
    } 
    catch(err:Error) {    
     outputBox.appendText(err.message); 
    } 
     checkChances(chances); 
     dbPath = new URLRequest(dbURL); 
}   

}

在第一个addEventListener上,你告诉它使用弱引用(该调用的最后一个参数)。你的loadXML函数是在你的getSettings()方法中定义的。一旦你离开getSettings()作用域,loadXML就会超出范围。剩下的引用loadXML的唯一事情就是事件监听器,但是因为你告诉它使用了一个不会阻止垃圾收集的弱引用。因此,在事件发生时,loadXML方法可能会被垃圾收集。我的猜测是,当你定义另一个侦听器时,在那里定义的匿名方法会保留getSettings()作用域(因为它是该方法作用域的一部分),这将保持范围内的loadXML()。

您真正应该做的是将您的loadXML方法重构为您的对象上的实际成员函数,而不是getSettings()中定义的匿名方法。这会使事情保持清洁,并且会阻止你看到的垃圾回收,因为只要对象有办法,方法就会保持在范围内。

如果由于某种原因你不想让loadXML成为一个成员函数,那么除去弱引用标志应该足以解决它。但是,由于这些匿名方法的工作方式,最终可能会导致内存泄漏。

的回答你的问题是没有, actionscript 3.0不需要XML的错误事件处理程序。它甚至不需要完整的处理程序!这就是.addEventListener()的要点,事件监听器是可选的。

对我来说听起来好像还有更多与您的代码在一起,然后您在这里呈现。
(你犯了错误事件监听器,然后一切正常,完全没有意义!)

你是否始终在同一位置执行文件?这是我的猜测,为什么XML不会加载,也许你把你的.swf文件移动到另一个文件夹?

+0

是的,我总是执行本地网络驱动器中的文件。将文件移动到我的桌面并在那里测试具有相同的结果。 – user54331 2009-01-29 15:17:52

这只是胡乱猜测,不过,是不是有可能是在程序的早期版本中,load()命令发出addEventListener()之前,和你重新排列它们(到正确顺序)时你添加了第二个错误侦听器?如果是这样,那肯定是一个时间问题。如果您还包含而不是工作的代码,这将会有所帮助。

UPDATE

我觉得Herms是正确的。当您添加一个单独的本地作用域侦听器作为弱引用时,不仅收听者本身,而且也将URLLoader对象在下载完成之前获取垃圾收集(因为没有侦听器,保留它是没有意义的) 。 (为什么这会发生在独立模式而不是Flash IDE中,这可能是偶然的,这取决于GC的工作原理。)当您添加第二个,强引用错误事件侦听器,tada,不再GCing。因此,要么尝试Herms的建议:使用更大范围的函数作为完成监听器,只需从addEventListener()调用中删除弱引用参数即可。

+0

不,我总是在加载命令之前有事件监听器。我发布了不起作用的代码。 – user54331 2009-01-29 15:10:02

+0

够公平的。但是,它可能只是我,但你说“我(意外的)修复是将一个事件监听器分配给加载器对象。”并在代码中列出错误事件侦听器。而且,这仍然是行不通的。那又是什么意外的修复? – 2009-01-29 15:14:46