在我正在开发的Flash游戏中,有一些设置是由外部XML文件设置的。当我通过Flash IDE运行SWF文件时,它加载正常。如果我运行与投影仪(.exe)或独立SWF文件相同的文件,则它不会加载XML文件。
我的(意外)修复是将错误事件侦听器分配给loader对象。当我再次发布文件时,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);
}
}
答案 0 :(得分:1)
在第一个addEventListener上,你告诉它使用弱引用(该调用的最后一个参数)。您的loadXML函数在getSettings()方法中定义。离开getSettings()范围后,loadXML超出范围。引用loadXML的唯一事情是事件监听器,但是因为你告诉它使用弱引用,它不会阻止它被垃圾收集。因此,在引发事件时,loadXML方法可能是垃圾回收。
我的猜测是,当你定义另一个监听器时,定义的匿名方法会保持getSettings()范围(因为它是该方法范围的一部分),这将使loadXML()保持在范围内。
你真正应该做的是将loadXML方法重构为对象的实际成员函数,而不是getSettings()中定义的匿名方法。这将使事情变得更清洁,并且会阻止您看到的垃圾收集,因为只要对象存在,该方法就会保留在范围内。
如果由于某种原因你不想让loadXML成为一个成员函数,那么删除弱引用标志应该足以修复它。但是,由于这些匿名方法的工作方式,您可能会因内存泄漏而导致内存泄漏。
答案 1 :(得分:0)
您的问题的答案是否定的,actionscript 3.0不需要XML的错误事件处理程序。它甚至不需要一个完整的处理程序!这就是.addEventListener(),事件监听器是可选的。
听起来我觉得你的代码还有很多,然后你就来这里了。
(你提出错误事件监听器,然后一切都工作o.k.,根本就没有意义!)
您是否始终从同一位置执行文件?这是我猜测为什么XML无法加载,也许你将.swf文件移动到另一个文件夹?
答案 2 :(得分:0)
这只是一个疯狂的猜测,但是在早期版本的程序中,load()
命令在 addEventListener()
之前发出了,而且当你添加第二个错误监听器时,你重新排序它们(到正确的顺序)?如果是这样,那肯定是一个时间问题。如果您还包含 not 工作的代码,将会很有帮助。
<强>更新强>
我认为Herms是正确的。当您将一个本地范围的侦听器添加为弱引用时,不仅是侦听器本身,而且还会使URLLoader
对象被垃圾回收(因为没有侦听器) ,在下载完成之前保持它是没有意义的。 (为什么这种情况发生在独立模式而不是Flash IDE中可能是偶然的,具体取决于GC的确切工作方式。)当您添加第二个强引用错误事件侦听器时, tada < / em>,不再是GCing。
因此,要么尝试Herms建议的内容:使用更宽范围的函数作为完成侦听器,或只需从addEventListener()
调用中删除弱引用参数。