2012-11-28 72 views
4

查看下一個代碼,告訴我你期望打印什麼。然後運行它並檢查發生了什麼。Flash事件執行順序

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 

    public class TestFlashEvents extends Sprite 
    { 
     private static const DUMMY_EVENT:String = "DummyEvent"; 
     private var dummyObjects:Vector.<DummyObject> = new Vector.<DummyObject>(100); 
     public function TestFlashEvents() 
     { 
      for(var i:int = 0; i < dummyObjects.length; i++){ 
       dummyObjects[i] = new DummyObject(this); 
       addEventListener(DUMMY_EVENT, dummyObjects[i].listener); 
      } 
      removeEventListener(DUMMY_EVENT, dummyObjects[41].listener); 
      dispatchEvent(new Event(DUMMY_EVENT)); 
     } 

     private var counter:int = 0; 
     public function onGettingEvent(dummyObject:DummyObject):void{ 
      if(counter == 25){ 
       for(var i:int = 0; i < 50; i++){ 
        removeEventListener(DUMMY_EVENT, dummyObjects[i].listener); 
        trace("Removing", dummyObjects[i].id); 
       } 
      } 
      trace("Handeling event", counter, dummyObject.id); 
      counter++; 
     } 
    } 
} 
import flash.events.Event; 

class DummyObject 
{ 
    private static var dummyObjectsCounter:int = 0; 

    public var id:String; 
    private var tester:TestFlashEvents; 

    public function DummyObject(tester:TestFlashEvents) 
    { 
     this.tester = tester; 
     id = "DummyObject " + dummyObjectsCounter; 
     dummyObjectsCounter++; 
    } 

    public function listener(event:Event):void{ 
     tester.onGettingEvent(this); 
    } 
} 

removeEventListener函數實際上不工作。告訴我你對此有何看法。我也在adobe中打開一個bug。

+0

-1對於聳人聽聞的標題:這幾乎肯定不是一個錯誤。 – JcFx

+0

@JCFx改變了它。下次你可以自己編輯它。我確實相信這是bug –

+0

不夠公平。 -1已刪除。 – JcFx

回答

2

此代碼表示Adobe在實際調用事件偵聽器之前緩存事件偵聽器列表。將一個特定事件的兩個偵聽器放在一個對象上是一種不尋常的行爲,但如果發生這種情況,Adobe會假定在實際修改此列表之前應調用所有偵聽器。我實際上期待着所有99個聽衆都能接聽電話。所以,這種行爲甚至可以通過設計來實現,因爲在處理單個事件時重新呈現事件偵聽器列表會給Flash帶來過重的負擔,因此這些滯後將會增加。沒有人想要落後。

+0

不完全緩存..但是如果一個事件被拋出,它將進入事件執行隊列。當你刪除eventlistener時,事件將在隊列中。它不是一個錯誤。它的邏輯方式。 – csomakk

0

這可以通過優先處理事件偵聽器來輕鬆解決。 這不是一個Flash錯誤,它就像Vesper所說的緩存事件監聽器來防止滯後。

以下是您的代碼的更新版本,標記addEventListener調用的優先級。

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 

    public class TestFlashEvents extends Sprite 
    { 
     private var _this = this; 
     private static const DUMMY_EVENT:String = "DummyEvent"; 
     private var dummyObjects:Vector.<DummyObject> = new Vector.<DummyObject>(100); 
     public function TestFlashEvents() 
     { 
      for(var i:int = 0; i < dummyObjects.length; i++) 
      { 
       dummyObjects[i] = new DummyObject(this); 
       addEventListener(DUMMY_EVENT, dummyObjects[i].listener, false, dummyObjects.length - i); 
      } 
      removeEventListener(DUMMY_EVENT, dummyObjects[41].listener); 
      dispatchEvent(new Event(DUMMY_EVENT)); 
     } 

     private var counter:int = 0; 
     public function onGettingEvent(dummyObject:DummyObject):void 
     { 
      if (counter == 25) 
      { 
       for (var i:int = 0; i < 50; i++) 
       { 
        removeEventListener(DUMMY_EVENT, dummyObjects[i].listener); 
        trace("Removing", dummyObjects[i].id); 
       } 
      } 
      trace("Handeling event", counter, dummyObject.id); 
      counter++; 
     } 
    } 
} 

import flash.events.Event; 

class DummyObject 
{ 
    private static var dummyObjectsCounter:int = 0; 

    public var id:String; 
    private var tester:TestFlashEvents; 

    public function DummyObject(tester:TestFlashEvents) 
    { 
     this.tester = tester; 
     id = "DummyObject " + dummyObjectsCounter; 
     dummyObjectsCounter++; 
    } 

    public function listener(event:Event):void{ 
     tester.onGettingEvent(this); 
    } 
} 
+0

現在這聽起來更麻煩了,然後再說。優先次序不應影響事件何時被移除。它沒有意義。關於@Vesper所說的,我找到了一種在O(1)中添加和刪除事件的方法,所以我認爲Adobe並不比我更糟,他們也可以做到這一點。這是一個錯誤!順便說一句,如果你嘗試在調度時添加事件(即使有優先級),它也不會起作用。 –

+0

優先級確實會影響事件隊列。如果一個事件優先於另一個事件,它將在隊列中首先被處理,並且隊列將被正確地更新,如果所有事件具有相同的優先級,隊列不應該被更新,因爲第一事件不再被更新重要的是最後... 這不是一個錯誤,這是架構按預期工作。 我明白你的擔憂,但是這個tbh,做這樣的事情可以用更清潔的方式解決...... –