2009-04-02 23 views
20

Chcę usunąć/wymuszać zbieranie śmieci na instancji klasy z poziomu samego siebie. Oczywiście, this = null i delete this nie działają. Czy mogę to zrobić w jakiś sposób, czy też szczerzę złe drzewo? Zasadniczo szukam jakiegoś destruktora ..Jak usunąć/gc obiekt w Actionscript 3?

Mam instancję klasy, która próbuje załadować plik XML, a jeśli plik nie zostanie znaleziony, chcę zniszczyć instancję, najlepiej od wewnątrz. Chodzi o to, aby zrobić pewne rzeczy w klasie nadrzędnej w zależności od tego, czy instancja podrzędna ma wartość zerową, czy nie.

Pomyślałem o rzuceniu wydarzenia rodzicowi i usunięciu go stamtąd, ale wolałbym to zrobić tylko wtedy, gdy nie ma innego sposobu.

Odpowiedz

22

Nie należy próbować usuwać obiektu z samego siebie - jest to zła praktyka, aw AS3 nie można tego zrobić na pewno.

Obiekt może zostać usunięty (to znaczy śmieci zebrane) tylko wtedy, gdy nie ma odniesień do tego obiektu. Ponieważ odniesienia zawsze są przekazywane przez wartość, a obiekt nie jest generalnie świadomy, które odniesienia do niego istnieją, nie można usunąć obiektu z samego siebie. Jedyną użyteczną rzeczą, jaką możesz zrobić, to stworzyć metodę, która wyczyści wszystkie zasoby używane przez instancję. Taka metoda będzie służyć jako destruktor, ale będziesz musiał ją wywołać ręcznie. Nie zapominaj, że detektory zdarzeń zapobiegają także czyszczeniu pamięci, chyba że je usuniesz.

Istnieje również różnica między delete "a właściwością i ustawieniem jej na null. Efektywnie delete usunie właściwość z instancji klasy dynamicznej. Natomiast ustawienie wartości nieruchomości na null nie spowoduje usunięcia nieruchomości, ale usunie wszelkie odniesienia tam przechowywane. W związku z tym obie akcje zniszczą referencję przechowywaną w niektórych nieruchomościach. Zauważ, że nie możesz delete obiektu, tylko właściwość.

Istnieje kilka hacków, które mogą być użyte do rozpoczęcia zbierania śmieci w odtwarzaczach flash 9 i starszych. Jednak ostatnio dostępne jest połączenie System.gc(), które robi to samo. Zauważ, że nie możesz naprawdę polegać na tym, że GC zostanie wywołany. To zależy od Flash Playera.

Powracając do pytania: Rzucanie wydarzenia i powiadomienie rodzica, że ​​coś poszło nie tak, to naprawdę dobry pomysł. Powinieneś się tego trzymać. Co więcej, lepiej jest, jeśli rodzic będzie wiedział o takim wydarzeniu w ten sposób, a nie wtedy, gdy odkryje, że niektóre właściwości zostały magicznie anulowane.

P.S .: Czytanie Granta Skinnera articles on memory w Flash Playerze to naprawdę dobry pomysł.

+0

"Należy zauważyć, że nie można usunąć obiektu, a jedynie właściwość." - Nie jestem pewien co masz na myśli. Co się stanie, jeśli moja własność jest przedmiotem? – Luke

+2

@Luke: Mam na myśli to, że właściwość obiektu A może zawierać odniesienie do jakiegoś obiektu B, ale 'delete A.prop' usunie tylko tę właściwość wraz z odniesieniem. To znaczy. A nie będzie mieć własności "prop", ale prawdopodobnie będą tam gdzieś odniesienia do obiektu B. Więc B nie otrzyma GC. – dragonfly

+6

'System.gc()' jest dostępny tylko dla wersji flash odtwarzacza. Powinieneś to poprawić, aby wspomnieć, że nie powinno się go używać do niczego innego niż debugowanie. –

1

AS3 nie daje żadnych destruktorów. Najlepsze, co możesz zrobić, to ustawić wszystkie odniesienia do null i trzymać kciuki - że GC to zauważy i zwolni pamięć.

+0

OK, ale jak ustawić zerową instancję klasy z wnętrza samej siebie? – evilpenguin

+0

@evilpenguin, chyba że używasz singleton, nie robisz tego z poziomu samej klasy. Robisz to od klasy, która stworzyła tę klasę. – KingNestor

+0

@evilpenguin: Zgodnie z sugestią, musisz to zrobić z zewnątrz. – dirkgently

1

Powinieneś mieć przeczytać o zbieranie śmieci pierwszy Grant.S napisał dobry artykuł na ten temat:

http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

Punktem nie ustawia samej klasy na wartość null, ale usuwa wszystkie jej odwołania, w tym detektory. Gdy zostanie całkowicie osierocony, śmieci mogą go podnieść w pewnym momencie.

Podstawowe przykład:

// References a newly created sprite 
var reference:Sprite = new Sprite(); 

// Removes the reference, the Sprite is now orphaned and will probably be garbage collected within some seconds. 
reference = null; 

Dobrą praktyką jest, aby systematycznie tworzyć „zniszczeniu” metody na wszystkich klas, które usuwa wszystkie swoje referencje wewnętrznych, zbywa bitmap, usuwa detektory zdarzeń itd., Potem ty będą musieli się tylko martwić o odłączenie zewnętrznych.

Jeśli używasz programu FLEX Builder, możesz użyć profilera, aby zobaczyć, w jaki sposób Flash Player obsługuje to wszystko wewnętrznie.

1

Oto nieobsługiwany sposób wymuszania zbierania śmieci od GSkinner.

try { 
    new LocalConnection().connect('foo'); 
    new LocalConnection().connect('foo'); 
} catch (e:*) {} 
// the GC will perform a full mark/sweep on the second call. 
5

Jeżeli obiekt dodano do DisplayContainer stosując metodę addChild() można usunąć przedmiot z pojemnika od wewnątrz obiektu, za pomocą parent.removeChild (to). Jeśli nie ma żadnych odniesień do obiektu po tym, zostanie on odebrany przez śmieciarz.

Jedyny problem występuje, gdy w obiekcie znajdują się detektory zdarzeń, które można albo usunąć ręcznie, albo pozwolić, aby garbage collector zrobił to za Ciebie, ustawiając wartość weakReference = true dla wszystkich detektorów.

Powiązane problemy