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):
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:
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:
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:
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.