AS3, das eine Funktion als Parameter übergibt, erzeugt Speicherlecks

8

Ich habe eine Funktion, die eine andere Funktion als Parameter hat. Etwas wie das:

%Vor%

Ich benutze es, indem ich eine Memberfunktion als einen Parameter übergebe, der immer dann aufgerufen werden soll, wenn das übergebene Ziel auf etwas trifft. Die Funktion wird oft als Rahmen bezeichnet. So wird es benutzt:

%Vor%

Die On-Hit-Funktion:

%Vor%

Wenn ich das mache, habe ich ein Speicherleck. Ich habe das Problem auf diese OnHits Methode isoliert und alles andere auskommentiert. onHits ist eine leere Methode ohne Code, onHitCB ist ebenfalls leer. Wenn ich den Aufruf von onHits auskommentiere, gibt es kein Speicherleck und wenn ich null anstelle von onHitCB überlasse, gibt es kein Speicherleck.

Es ist klar, wenn ich HitCB als Parameter weitergebe, ist das das Problem. Also dachte ich, es könnte sein, dass Flash Speicher zum Erstellen des Funktionszeigers zuweist und es nicht freigibt, aber ich System.gc () jeden Frame im Debug-Modus anrufe und das Leck immer noch da ist. Das würde bedeuten, dass dies entweder ein Fehler im SDK ist oder ich etwas nicht richtig mache.

Ich habe eine seltsame Problemumgehung gefunden, indem ich eine Variable beibehalten habe, die auf die Funktion zeigt, die ich im Konstruktor meines Objekts zugewiesen habe:

%Vor%

und dies löscht den Speicherverlust , auch wenn ich HitCB als Parameter weitergebe . Das würde bedeuten, dass es nicht die "Getter" -Funktion ist, die onHitCB erhält, sondern etwas anderes, das den Speicherleck verursacht?

Ich bin sehr verwirrt. Wie kann dies zu einem Speicherverlust führen:

%Vor%

aber nicht das? :

%Vor%

und gibt es eine Möglichkeit, diese Problemumgehung nicht zu machen?

    
Godfather 06.09.2011, 08:58
quelle

4 Antworten

5
  

[...] gebundene Methoden werden automatisch erstellt, wenn Sie eine Methode als Parameter übergeben. Gebundene Methoden stellen sicher, dass das Schlüsselwort this immer auf das Objekt oder die Klasse verweist, in der eine Methode definiert ist. Quelle

Das klingt, als würde das Erstellen eines Verweises auf eine Methode keinen einfachen Getter verwenden. Ein neues Methodenabschlussobjekt wird generiert . Also ist deine Annahme richtig.

Ich frage mich, warum die Referenzen nicht für jede Instanz zwischengespeichert werden und warum sie nicht als Müll gesammelt werden. Vermeiden Sie es besser, mehrere Referenzen zu erstellen. Eine Methode nur einmal zu referenzieren ist genau das, was ich tun würde, wenn ich diese Methode an mehreren Stellen verwenden müsste. Daher würde ich die meiste Zeit nicht als Workaround, sondern als gute DRY-Praxis bezeichnen. In Ihrem Beispiel macht es natürlich Sinn, vorausgesetzt, eine Methodenreferenz würde einen einfachen Getter verwenden.

    
Kapep 06.09.2011, 09:46
quelle
1

Weitere Informationen darüber, was genau und was nicht zu Speicherverlusten führt, wenn Sie funktionale Techniken verwenden, finden Sie unter Ссылка . Seien Sie sich auch bewusst, dass die Verwendung von statischen Methoden wie diese wirklich schlechte Übung ist (http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/), und Sie fangen gerade erst an begegnen Sie den vielen Problemen, die durch die Verwendung dieser Technik verursacht werden. Es hört sich so an, als ob Sie in Ihrem Projekt früh genug sind, dass Sie sich diesem Pfad nicht vollständig verschrieben haben. Daher sollten Sie sich vielleicht andere Möglichkeiten ansehen, dies zu programmieren.

    
Amy Blankenship 06.09.2011 11:12
quelle
0

Ich bin mir nicht sicher, worüber dein Code in der onHits-Funktion steht, aber wenn es keine zusätzliche Zeit erfordert, um in einem anderen Zyklus fertig zu werden. dann empfehle ich dir, so zu machen:

%Vor%

und

%Vor%     
Jevgenij Dmitrijev 06.09.2011 09:15
quelle
-1

Und deshalb machen wir im OOP-Stil nicht so etwas.
Am besten ist es, es richtig zu machen und fügen Sie den Callback der CollisionManager-Klasse hinzu. Der Grund, warum Sie eine lokale Referenz beibehalten können, liegt daran, dass die Funktion niemals den Gültigkeitsbereich verliert, da diese Variable die Referenz enthält > Sobald etwas den Rahmen verliert, wird es nahezu unmöglich, es zu erfassen.

Versuchen Sie es und beobachten Sie, wie Sie den Umfang verlieren.

%Vor%     
The_asMan 08.09.2011 01:12
quelle