2010-11-22 13 views
0

Je vais essayer d'être aussi concis que possible. J'ai un certain nombre d'objets dans un tableau, et je fais une demande d'écouteurs d'événement à chacun en utilisant des fermetures:Qu'est-ce qui peut empêcher les fermetures de gestion d'événements de cesser de fonctionner?

//reduced to the logic in question: 
buttons.forEach(function(button:EventDispatcher, i:int, list:Array):void { 
    button.addEventListener(MouseEvent.MOUSE_OVER, function(e:Event):void { 
    button.filters = [button_glow_filter]; 
    }); 
}); 
//button-specific click handlers: 
buttons[0].addEventListener(MouseEvent.MOUSE_CLICK, handle_some_action); 

Cela fonctionne parfaitement pendant un certain temps, jusqu'à ce que j'effectuer une action sans rapport sur l'interface utilisateur. C'est un système très complexe, donc je ne suis pas vraiment sûr de ce qui se passe. Je peux confirmer que l'action non liée n'a aucun effet direct sur l'objet qui contient les boutons ou les boutons eux-mêmes (au moins, cela ne change rien via les interfaces publiques). Les boutons existent toujours et les écouteurs d'événement click fonctionnent toujours correctement, car ceux-ci sont affectés individuellement à de vraies fonctions sur l'interface de la classe.

Ma question est donc: est-ce que quelqu'un sait ce qui peut amener ces fermetures à cesser de gérer les événements MouseOver sans avoir d'autre effet perceptible sur les objets liés?

Il y a un certain nombre de façons d'accomplir ce comportement de MouseOver, et pour l'instant je suis passé à un qui fonctionne, mais j'aimerais toujours connaître la réponse à cette question pour référence future.

Répondre

1

J'ai trouvé le coupable probable presque immédiatement après l'affichage: la collecte des ordures. Il n'a fallu que quelques minutes pour confirmer. C'est exactement ce à quoi sert le paramètre useWeakReference dans l'interface addEventListener; il est par défaut vrai. En le définissant sur false, il empêche les écouteurs assignés de cette manière d'être récupérés. Le code correct est:

buttons.forEach(function(button:EventDispatcher, i:int, list:Array):void { 
    button.addEventListener(MouseEvent.MOUSE_OVER, function(e:Event):void { 
    button.filters = [button_glow_filter]; 
    }, false, 0, false); 
}); 
+3

'useWeakReference' est défini par défaut sur false. On dirait que vous pourriez avoir un problème de GC, mais je doute de ne pas passer 'false' explicitement est le coupable. –

+0

Est-il possible que quelque chose dans une autre partie de votre application écrase la référence à 'button_glow_filter', provoquant l'extinction des boutons? – martineno

+0

Je pense que vous pourriez avoir des problèmes de fermeture. Je veux dire avec les deux fonctions anonymes là-bas, plutôt que votre vie privée. Pour une approche globale de la résolution des problèmes de récupération de place, essayez de modifier sans discrimination les variables locales en variables membres et les fonctions anonymes en fonctions membres. Juan avait raison à propos de useWeakReference par défaut à faux cependant. –