2009-01-28 108 views
2

在我正在開發的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); 
}   

}

回答

1

在第一個addEventListener上,你告訴它使用弱引用(該調用的最後一個參數)。你的loadXML函數是在你的getSettings()方法中定義的。一旦你離開getSettings()作用域,loadXML就會超出範圍。剩下的引用loadXML的唯一事情就是事件監聽器,但是因爲你告訴它使用了一個不會阻止垃圾收集的弱引用。因此,在事件發生時,loadXML方法可能會被垃圾收集。我的猜測是,當你定義另一個偵聽器時,在那裏定義的匿名方法會保留getSettings()作用域(因爲它是該方法作用域的一部分),這將保持範圍內的loadXML()。

您真正應該做的是將您的loadXML方法重構爲您的對象上的實際成員函數,而不是getSettings()中定義的匿名方法。這會使事情保持清潔,並且會阻止你看到的垃圾回收,因爲只要對象有辦法,方法就會保持在範圍內。

如果由於某種原因你不想讓loadXML成爲一個成員函數,那麼除去弱引用標誌應該足以解決它。但是,由於這些匿名方法的工作方式,最終可能會導致內存泄漏。

0

的回答你的問題是沒有, actionscript 3.0不需要XML的錯誤事件處理程序。它甚至不需要完整的處理程序!這就是.addEventListener()的要點,事件監聽器是可選的。

對我來說聽起來好像還有更多與您的代碼在一起,然後您在這裏呈現。
(你犯了錯誤事件監聽器,然後一切正常,完全沒有意義!)

你是否始終在同一位置執行文件?這是我的猜測,爲什麼XML不會加載,也許你把你的.swf文件移動到另一個文件夾?

+0

是的,我總是執行本地網絡驅動器中的文件。將文件移動到我的桌面並在那裏測試具有相同的結果。 – user54331 2009-01-29 15:17:52

0

這只是胡亂猜測,不過,是不是有可能是在程序的早期版本中,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

相關問題