Petit conseil Comment déboguer une erreur AS3 n ° 1009

L’une des questions les plus courantes que je vois sur les forums et que je reçois de mes collègues est de savoir comment déboguer l’erreur 1009, également connue sous le nom «Erreur de référence d’objet Null». Ou, comme je l'appelle, le «Erreur de Mosquito Annoying From Hell». Cela revient souvent et malheureusement, l'erreur elle-même ne contient pas beaucoup d'informations sur la source de l'erreur. Dans cette astuce, nous allons examiner quelques étapes que vous pouvez suivre pour retrouver ce moustique et l’écraser..


introduction

Cette pièce est la première suite à la plus générale? Correction de bugs dans AS3? Didacticiel. Si vous souhaitez mieux comprendre certaines des techniques de cette astuce, vous voudrez peut-être le lire en entier en premier..


Étape 1: comprendre l'erreur

Il est dommage qu'Adobe ne fournisse pas (ou ne puisse pas) plus d'informations sur la cause de cette erreur. Tout d'abord, son libellé est plutôt obtus (un peu comme toutes leurs erreurs, mais ceci plus que beaucoup d'autres):

TypeError: Erreur n ° 1009: Impossible d'accéder à une propriété ou à une méthode d'une référence d'objet null

Essayons de mettre cela dans les termes de tous les jours. L'erreur 1009 signifie que vous avez essayé de faire quelque chose avec une variable dont vous supposez qu'elle a une valeur, mais ce n'est pas le cas. Flash n'aime pas ça. Vous n'aimeriez pas ça non plus; imaginez que vous aviez un verre que vous supposiez rempli du délicieux breuvage de votre choix, mais qui était vraiment vide. Vous attrapez le verre et attendez-vous une gorgée rafraîchissante, mais vous sentez plutôt le poids décevant d'un verre vide. C'est votre propre erreur personnelle 1009.

Dans ActionScript, si vous procédez ainsi:

 var s: String; trace (s.toUpperCase ());

Flash va brûler fort (un terme technique pour "produire une erreur") lorsque vous exécutez le code. La variable s peut avoir été déclaré, mais sa valeur est nul (nous n’avons jamais défini la valeur, nous avons simplement déclaré la variable), appelant ainsi le toUpperCase la méthode est gênante.

Pour être clair, parce que s est déclaré comme Chaîne, la compilateur ne pose aucun problème avec le code: il existe une variable appelée s, c'est un Chaîne, et toUpperCase est une méthode valide pour faire appel à Chaînes. L'erreur que nous obtenons est un temps d'exécution erreur, ce qui signifie que nous ne l'obtenons que lorsque nous exécutons le fichier SWF. C’est seulement lorsque la logique est réalisée que nous pouvons maintenant voir comment cela se passe..


Étape 2: Autoriser le débogage

Comme pour toute erreur d'exécution, il est parfois assez facile de dire ce qui se passe sans aucune information supplémentaire. Mais d'autres fois, il est utile de réduire cela davantage. À ce stade, essayez d'activer «Autoriser le débogage». Lorsque cela est activé, vous obtenez des erreurs qui vous donnent également des numéros de ligne. Sinon, vous pourrez peut-être? Déboguer un film? en appuyant sur Commande-Maj-Retour / Contrôle-Maj-Entrée.

Pour ce faire, reportez-vous à l’article intitulée Conseils généraux de débogage,? Correction de bugs dans AS3.?

Parfois, cela suffit. Connaître la ligne spécifique pourrait être toute l'information dont vous aviez besoin. Sinon, nous allons creuser un peu plus dans la prochaine étape.

Notre cher éditeur, Michael James Williams, a résumé le but de cette étape dans un limerick, que je suis heureux de vous présenter maintenant avec son aimable autorisation:

Erreur AS3 un-oh-oh-neuf
N'est jamais un très bon signe.
Pas besoin de s'inquiéter,
Appuyez sur Ctrl-Maj-Retour
Et ça va localiser la cause (enfin, la ligne).


Étape 3: commencer le traçage

Si vous avez localisé la ligne incriminée mais que vous ne savez toujours pas ce qui se passe, choisissez-la séparément. Prenez toutes les variables de cette ligne et tracez-les antérieur à l'erreur.

Comme l'erreur survient lors de l'accès à une propriété ou de l'appel d'une méthode sur une variable null, pour couvrir vos bases, vous devez suivre toutes les variables et propriétés immédiatement suivies d'un point. Par exemple, prenons cette ligne de code:

 myArray.push (someSprite.stage.align.toLowerCase ());

Certes, il s’agit d’un code assez artificiel pour lequel je ne peux imaginer d’utilisation pratique, mais vous devez identifier quatre total possible nul valeurs auxquelles on accède avec le point:

  • mon tableau: nous appelons le pousser méthode sur cette variable
  • un peu d'esprit: nous accédons au étape propriété
  • étape: nous accédons au aligner propriété
  • aligner: nous appelons le toLowerCase méthode

Votre code de débogage pourrait ressembler à ceci:

 trace ("myArray:", myArray); trace ("someSprite:", someSprite); trace ("someSprite.stage:", someSprite.stage); trace ("someSprite.stage.align:", someSprite.stage.align);

L'ordre est important. si un peu d'esprit est l'objet nul, mais vous testez someSprite.stage.align avant de tester un peu d'esprit, vous vous retrouvez avec des résultats moins définitifs.

Maintenant, le bon sens joue également dans cela. Dans mon exemple, si étape existe, alors aligner assurément aura une valeur; la Étape a toujours un aligner réglage, même si c'est la valeur par défaut.

En règle générale, vous verrez quelque chose comme ce qui suit:

 myArray: [? des trucs dans le tableau? ] someSprite: [objet Sprite] someSprite.stage: null Erreur # 1009:? 

Ce qui devrait vous indiquer que le étape la propriété est nul, et maintenant vous pouvez y remédier.


Étape 4: Trouver une solution

La solution la plus simple consiste à résumer la déclaration incriminée dans un? If? block, et n'exécutez le bloc que si la variable en question n'est pas nulle. Donc, en supposant que dans notre exemple précédent, il était en fait étape c'était nul, nous pourrions faire quelque chose comme ceci:

 if (someSprite.stage) myArray.push (someSprite.stage.align.toLowerCase ()); 

Ce test - if (someSprite.stage) - reviendra vrai s'il y a une valeur (quelle que soit la valeur), et faux si c'est nul. En général, cette notation fonctionne. vous pouvez toujours utiliser if (someSprite.stage! = null) si tu préfères. Nombres présente une situation légèrement différente, cependant. Si la Nombre a une valeur de 0, alors techniquement, il a une valeur, mais les tests if (someNumberThatEqualsZero) va évaluer à faux. Pour Nombres vous pouvez utiliser le isNaN () fonction permettant de déterminer si une valeur numérique valide est stockée dans une variable donnée.

En tout état de cause, cette technique est un moyen simple d’éviter l’erreur. Si la variable sur laquelle vous souhaitez effectuer une opération n'est pas définie, ne la faites pas. S'il n'y a pas de boisson savoureuse dans notre verre, ne le prenez pas. Assez simple.

Mais cette approche n’est réalisable que si la logique est optionnelle. Si la logique est requise, vous pouvez peut-être fournir une valeur par défaut à la variable douteuse avant l'opération d'erreur. Par exemple, si mon tableau a le potentiel d'être nul, mais il est impératif que ce ne soit pas le cas, nous pouvons le faire:

 if (! myArray) myArray = [];  myArray.push (someSprite.stage.align.toLowerCase ());

Cela va d'abord vérifier si le tableau est nul. Si c'est le cas, initialisez-le dans un tableau vide (un tableau vide est une valeur valide. Il peut être vide, mais c'est un tableau et non nul) avant d’exécuter la ligne de code artificielle. Si ce n'est pas nul, passez directement à la ligne de code artificielle. En termes réels, si notre verre est vide, remplissez-le avec une délicieuse boisson avant de le ramasser..

De plus, si mon tableau est une propriété d'instance de la classe dans laquelle cette ligne de code est en cours d'exécution, vous pouvez assurer en toute sécurité une valeur valide en initialisant vos propriétés lors de l'initialisation de l'objet.

Et si la logique était nécessaire, mais que la variable en question ne soit pas aussi facilement sous notre contrôle? Par exemple, que se passe-t-il si notre ligne de code artificielle est requise, mais que la variable douteuse est un peu? Nous ne pouvons pas simplement régler le étape propriété; qui est contrôlé en interne pour DisplayObject et est en lecture seule pour nous, simples mortels. Ensuite, vous devrez peut-être être astucieux et lire l'étape suivante..


Étape 5: Faire face à un nul étape

Il existe probablement un nombre infini de scénarios dans lesquels une variable ou une propriété donnée pourrait être nul. De toute évidence, je ne peux pas tous les couvrir dans un conseil rapide. Il existe cependant une situation spécifique qui se répète encore et encore.

Disons que vous écrivez du code qui ressemble à ceci:

 Classe publique QuickSprite étend Sprite fonction publique QuickSprite () stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove);  fonction privée onMove (e: MouseEvent): void var color: ColorTransform = new ColorTransform (); color.color = stage.mouseX / stage.stageWidth * 0xFFFFFF; this.transform.colorTransform = color; 

Un autre morceau de code artificiel (qui pourrait provoquer des crises - considérez-vous comme étant averti), mais au fond, l’idée est que vous avez un Lutin sous-classe et vous définissez cela comme classe pour un clip sur la scène, à l'aide de Flash IDE.

Cependant, vous décidez que vous voulez travailler avec ces QuickSprites par programmation. Donc, vous essayez ceci:

 var qs: QuickSprite = new QuickSprite (); addChild (qs);

Et vous obtenez l'erreur maudite 1009. Pourquoi? Parce que dans le QuickSprite constructeur, vous accédez au étape propriété (héritée de DisplayObject). Lorsque l'objet est entièrement créé avec du code, ce n'est pas sur la scène au moment où cette ligne de code s'exécute, ce qui signifie étape est nul et vous obtenez l'erreur. le QuickSprite est ajouté à la ligne suivante, mais ce n'est pas assez tôt. Si l'instance est créée en faisant glisser un symbole hors de la bibliothèque et sur la scène, il y a un peu de magie à l'œuvre dans les coulisses qui garantit que l'instance est sur la scène (c'est-à-dire le étape la propriété est définie) pendant le constructeur.

Alors, voici ce que vous faites: vous testez l’existence d’une valeur pour étape. En fonction du résultat, vous pouvez exécuter le code de configuration immédiatement ou configurer un écouteur d'événement différent pour QuickSprite est ajouté à la scène. Quelque chose comme ça:

 fonction publique QuickSprite () if (stage) init ();  else this.addEventListener (Event.ADDED_TO_STAGE, init);  fonction privée init (e: Event = null) this.removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove); 

Si on déplace le étape en ligne à une fonction différente, et n’appelez cette fonction que lorsque nous avons une étape, nous sommes paramétrés. Si étape existe depuis le début, allez-y et courez init () tout de suite. Sinon, nous utiliserons init () en tant que fonction d'écoute d'événement pour ADDED_TO_STAGE, à ce stade, nous aurons une valeur d'étape et nous pourrons exécuter le code. Maintenant, nous pouvons utiliser la classe pour la connexion à IDE Sprite ou complètement par programmation.

Cela fonctionne aussi bien dans les classes de document. Lorsque vous exécutez un fichier SWF seul, la classe de document a un accès immédiat à étape. Toutefois, si vous chargez ce fichier SWF dans un autre fichier SWF, le code de la pile d'initialisation de la classe de document est exécuté avant que le fichier SWF chargé ne soit ajouté à l'affichage. Un similaire étape-Cette astuce vous permettra de travailler avec le fichier SWF en tant que pièce autonome et en tant que fichier SWF chargé dans un fichier SWF contenant.


C'est tout

Merci d'avoir lu ce petit conseil! J'espère que vous savez un peu comment l'erreur 1009 se produit et comment vous pouvez la déboguer. Restez à l'écoute pour plus de conseils rapides sur d'autres erreurs courantes.