2010-11-16 7 views
1

Je suis curieux de savoir quels sont les avantages de l'utilisation de hasEventListener() lors de l'envoi d'un événement à l'aveugle?Pourquoi utiliser IEventDispatcher.hasListener()?

Par exemple, je vois dans les extraits de code du framework Flex telles que les suivantes:

// from ArrayList.setItemAt() 
var hasCollectionListener:Boolean = hasEventListener(CollectionEvent.COLLECTION_CHANGE); 
if (hasCollectionListener) 
{ 
    dispatchEvent(new CollectionEvent(....)) 
} 

Je suppose que ce infère des avantages de performance de ne pas l'envoi de l'événement si personne n'écoute, par rapport à l'aveuglette l'envoi, indépendamment du fait qu'il y ait des auditeurs attachés.

Cependant, cela ne semble pas logique.

Les écouteurs sont stockés en interne dans un hashmap performant. J'aurais pensé que vérifier si un écouteur existe est à peu près aussi performant qu'itérer à travers le tableau vide d'auditeurs.

Par conséquent, pourquoi prendre la peine de vérifier, et pas simplement invoquer aveuglément la méthode dispatchEvent? L'exemple de code d'origine est sensiblement plus maladroit que s'ils avaient simplement envoyé l'événement.

Cordialement,

Marty

Répondre

0

Pour autant que je peux dire, l'exécution de cette vérification est redondante. Si personne n'écoute, alors il n'y a rien dans la collection des listeners, donc dispatchEvent serait très rapide ... probablement aussi rapide que de demander s'il y a des écouteurs ... du moins à partir d'un niveau macro. Je suppose qu'un passage rapide à travers un profileur nous dirait à coup sûr ... Ce type de pré-optimisation introduit seulement plus de code et introduit donc les chances de stoopid copier/coller des bogues, sauf si vous savez avec certitude qu'il y a un pref problème ici et que cela permet de le soulager.

Il existe cependant quelques utilisations pour l'appel hasEventListener. Quelque chose comme cela aurait du sens:

if(hasEventListener("HeavyComputationChanged")) { 
    doSomeHeavyComputation(); 
    dispatchEvent("HeavyComputationChanged"); 
} 
+0

Oui, un peu ce que je pensais. –

+0

Malheureusement, cette vérification n'est pas redondante. 'dispatchEvent (new Event (" foo "))' crée toujours un nouvel objet de type 'Event' et le distribue. Peu importe s'il y a des auditeurs enregistrés ou non. Voir ma réponse pour plus d'informations. –

+0

Fonctionnellement, il est redondant. Cela ressemble à une micro optimisation pour moi ... Ce n'est pas comme si les objets Event sont terriblement grands ... J'essaie d'éviter les micro optimisations en faveur de moins de code dans la plupart des cas. –

0

Est-ce que la méthode de réception font un appel à Event.stopPropagation() ou Event.stopImmediatePropagation()?

Je peux voir qu'ils voudraient vérifier si l'écouteur d'événement était là s'ils ne veulent pas qu'il fasse du bruit aux autres écouteurs dans l'application. Si l'écouteur n'était pas là, il ne serait pas capable d'empêcher la propagation jusqu'à ce qu'il mette quelque chose d'autre comme un autre composant du même type!

1

L'envoi d'événements même si aucun écouteur d'événement n'est enregistré peut avoir un impact sur les performances de votre application. Donc, en utilisant hasEventListener() est considéré comme la meilleure pratique.

Il y a une longue discussion en cours sur le bugtracker d'Adobe sur ce sujet: http://bugs.adobe.com/jira/browse/SDK-24249

En bref: Lorsque vous écrivez dispatchEvent(new Event("foo")) un nouvel objet de type Event est créé et l'événement est distribué. Finalement, le GC arrive et supprime l'objet événement de la mémoire. Vous ne remarquerez aucune différence dans les situations où l'événement ne se déclenche que quelques fois. Dans le cas de liaisons ou d'autres événements distribués dans un grand nombre, l'utilisation de hasEventListener() peut faire la différence.

Depuis Flex 4, le code généré par le compilateur lorsque vous utilisez [Bindable] utilise toujours hasEventListener() avant d'envoyer un événement.

+0

Droite. Il s'agit de la consommation de mémoire, pas de la répartition des performances. Le test de hasEventListener() est un moyen d'éviter le coût de création (puis de collecte) d'une instance d'événement. – verveguy

Questions connexes