masz to opisane w helpie, chyba łatwiej jest wcisnąć F1 niż zadać pytanie na forum... poczytaj np. http://gingerbinger.com/2010/07/actionscript-3-0-events-the-myth-of-useweakreference/. a po naszemu: GC usuwa co jakiś czas z pamięci obiekty, które nie odwołują się do istniejących poza nimi obiektów i do których nie odwołują się inne obiekty, tzn. nie mają referencji. jeśli obiekt trzyma w sobie referencję do jakiejś statycznej zmiennej, to nie będzie nigdy zwolniony, a jeśli trzyma referencję do zmiennej niestatycznej, to będzie żył co najmniej tak długo, jak ta zmienna. jeśli jednak referencja będzie typu weak, to GC nie będzie brał jej pod uwagę przy sprawdzaniu, czy posiadacz tej referencji może zostać usunięty z pamięci.
tutaj powoduje to, że nie musisz pamiętać o odczepieniu każdego listenera, jednak może też spowodować efekt uboczny w postaci zwolnienia obiektu zanim jeszcze dane zostaną dociągnięte i zostanie wywołany EventListener. jeśli więc nie łapiesz do końca, jak działa ten mechanizm, to użyj innego - dla każdego addEventListener (i pokrewnych metod) MUSI być zawsze wywołany removeEventListener i to niezależnie od tego, czy ściągnięcie danych się udało czy nie. jest jeszcze jedna alternatywa - dla każdego webserwisu robisz jeden obiekt obsługujący go w ramach danej klasy/pliku as i raz tylko podłączasz do niego listener na dany event, przy czym każdy listener może być zdefiniowany tylko w tej klasie, w której istnieje obiekt opakowujący webserwis; w efekcie kiedy przestajesz używać głównej klasy (np. zamykasz okno modalne) to GC będzie mógł posprzątać całość.
poniższy kod jest napisany brzydko i z palca, chodzi tylko o zaprezentowanie idei, nie wyciągaj z tego wniosków na temat tego jak formatować kod.
pierwszy sposób (weak reference):
Kopiuj
var ws = new WS()
function OnClick(e) { ws.addEventListener(E.A, onA, false, 0, true); ws.addEventListener(E.Fail, ws.onFail, false, 0, true); ws.getA(); }
function onA(e) { ... }
function onFail(e) { ... }
pierwszy sposób w wersji mogącej spowodować niewykonanie handlera:
Kopiuj
function OnClick(e) {
var ws = new WS(); ws.addEventListener(E.A, onA, false, 0, true); ws.addEventListener(E.Fail, ws.onFail, false, 0, true);
ws.getA();
} // po wyjściu z tej metody obiekt ws może być od razu sprzątnięty z pamięci i onA ani onFail nigdy się nie wykonają
function onA(e) { ... }
function onFail(e) { ... }
drugi, moim zdaniem najlepszy sposób - zawsze sprzątać po sobie:
Kopiuj
function OnClick(e) {
var ws = new WS(); ws.addEventListener(E.A, onA); ws.addEventListener(E.Fail, ws.onFail);
ws.getA();
}
function onA(e) { e.target.removeEventListener(onA); e.target.removeEventListener(onFail); ... }
function onFail(e) { e.target.removeEventListener(onA); e.target.removeEventListener(onFail); ... }
trzeci, brzydki, ale najłatwiejszy sposób:
Kopiuj
var ws;
function init() {
ws = new WS();
ws.addEventListener(E.A, onA); ws.addEventListener(E.Fail, ws.onFail); // listenery przyczepiane RAZ na czas życia obiektu this
}
function OnClick(e) { ws.getA(); }
function onA(e) { ... }
function onFail(e) { ... }
// listenery zginą razem z obiektem this, a wtedy będzie mógł zginąć obiekt ws też powiązany tylko z obiektem this
pamiętaj, że masz kilka eventów sygnalizujących błędy.