ActionScript 3
Comprendre le "Erreur 1009: Impossible d'accéder à une propriété ou une méthode d'une référence d'objet null"
Recherche…
Introduction
null
. Les exemples fournis exposent divers cas où cette erreur survient, ainsi que des recommandations sur la manière d’atténuer cette erreur.
Remarques
Le redoutable et souvent demandé "Erreur 1009: Impossible d'accéder à une propriété ou une méthode d'une référence d'objet NULL" est un signal que certaines des données apparaissent nulles, mais est essayé d'être utilisé comme un objet rempli. Il existe plusieurs types de problèmes qui peuvent provoquer ce comportement, et chacun doit être testé avec le code où l'erreur est apparue.
La scène n'est pas disponible
Parfois, les développeurs écrivent du code pour accéder à la stage
, ou à la phase Flash, pour ajouter des écouteurs. Il peut fonctionner pour la première fois, puis soudainement ne plus fonctionner et produire l'erreur 1009. Le code en question peut même figurer sur la timeline, car c'est la première initiative à y ajouter du code, et de nombreux didacticiels existent encore. couche de code de ligne de temps pour placer le code.
public class Main extends MovieClip {
public function Main() {
stage.addEventListener(Event.ENTER_FRAME,update); // here
La raison pour laquelle ce code ne fonctionne pas est simple: un objet d'affichage est d'abord instancié, puis ajouté à la liste d'affichage, et alors qu'il est en dehors de la liste d'affichage, l' stage
est nulle.
Pire si le code comme ça:
stage.addEventListener(Event.ENTER_FRAME,update); // here
est placé sur la timeline. Il peut même fonctionner pendant un certain temps, tandis que l'objet Main
est placé sur la scène via l'interface graphique. Ensuite, leur fichier SWF est chargé depuis un autre fichier SWF, et le code est brisé tout à coup. Cela se produit parce que les Main
cadres de sont construits d'une manière différente lorsque le fichier SWF est chargé directement par le joueur et lorsque le chargement est traité de manière asynchrone. La solution consiste à utiliser Event.ADDED_TO_STAGE
listener, à y placer tout le code qui adresse les étapes et à placer l'écouteur lui-même dans un fichier AS au lieu du scénario.
Invalid typecast
function listener(e:Event):void {
var m:MovieClip=e.target as MovieClip;
m.x++;
}
Si un tel écouteur est associé à un objet qui n'est pas un descendant de MovieClip
(par exemple, un Sprite
), le transtypage échouera et toute opération ultérieure avec son résultat lancera l'erreur 1009.
Objet non confirmé
var a:Object;
trace(a); // null
trace(a.b); // Error 1009
Ici, une référence d'objet est déclarée, mais on ne lui attribue jamais de valeur, que ce soit avec new
ou l'affectation d'une valeur non nulle. Demander ses propriétés ou sa méthode entraîne une erreur 1009.
Expression multiniveau
x=anObject.aProperty.anotherProperty.getSomething().data;
Ici, tout objet avant le point peut être nul, et l'utilisation de méthodes qui renvoient des objets complexes ne fait qu'augmenter la complication du débogage de l'erreur nulle. Dans le pire des cas, si la méthode est sujette à des défaillances externes, par exemple, récupérer des données sur le réseau.
Résultat de la fonction non traité
s=this.getChildByName("garbage");
if (s.parent==this) {...}
getChildByName()
est l'une des nombreuses fonctions pouvant renvoyer null si une erreur s'est produite lors du traitement de son entrée. Par conséquent, si vous recevez un objet d'une fonction pouvant éventuellement renvoyer null, vérifiez d'abord la valeur null. Ici, une propriété est instantanément interrogée sans d'abord vérifier si s
est nul, cela générera l'erreur 1009.
Auditeur d'événement oublié
addEventListener(Event.ENTER_FRAME,moveChild);
function moveChild(e:Event):void {
childMC.x++;
if (childMC.x>1000) {
gotoAndStop(2);
}
}
Cet exemple déplacera le childMC
(ajouté à Main
au moment du design) mais lancera instantanément un 1009 dès que gotoAndStop()
sera childMC
, si cet childMC
n'existe pas sur le frame 2. La raison principale est que chaque fois qu'une tête de lecture passe une image clé (un cadre qui n'hérite pas de l'ensemble d'objets précédent), soit en utilisant gotoAndStop()
, gotoAndPlay()
avec une image de séparation de l'image en cours par une image clé, soit en lecture normale si le fichier SWF est un animation, le contenu de l'image en cours est détruit et le nouveau contenu est créé en utilisant les données stockées à partir de l'interface graphique. Ainsi, si le nouveau cadre n'a pas d'enfant nommé childMC
, la demande de propriété renverra null et 1009 sera renvoyé.
Le même principe s'applique si vous ajoutez deux écouteurs d'événement, mais n'en supprimez qu'un, ou ajoutez un écouteur à un objet, mais essayez de le supprimer d'un autre. L'appel removeEventListener
ne vous avertira pas si un écouteur d'événement respectif n'a pas été associé à l'objet, lisez donc le code qui ajoute et supprime soigneusement les écouteurs d'événements.
Notez également que l'utilisation des objets Timer
, appelant setInterval()
et setTimeout()
crée également des écouteurs d'événement, et ceux-ci doivent également être effacés correctement.
Référence invalidée à un objet basé sur des images
Parfois, gotoAndStop()
est appelé au milieu du code qui fait référence à certaines propriétés basées sur des images. Mais, juste après la modification de l'image, tous les liens vers les propriétés qui existaient sur l'image en cours sont invalidés, de sorte que tout traitement les impliquant doit être immédiatement arrêté.
Il existe deux scénarios généraux de ce type de traitement: Tout d'abord, une boucle ne se termine pas après l' gotoAndStop()
à gotoAndStop()
, comme ici:
for each (bullet in bullets) {
if (player.hitTestObject(bullet)) gotoAndStop("gameOver");
}
Ici, une erreur 1009 signifie que le player
MC a été détruit pendant le traitement de l'appel gotoAndStop()
, mais que la boucle continue et renvoie le lien maintenant nul pour obtenir hitTestObject()
. Si la condition if (bullet.hitTestObject(player))
place, l'erreur serait # 2007 "Le paramètre hitTestObject ne doit pas être nul". La solution consiste à placer une déclaration de return
juste après avoir appelé gotoAndStop()
.
Le deuxième cas est constitué d'écouteurs multiples sur le même événement. Comme ça:
stage.addEventListener(Event.ENTER_FRAME,func1);
stage.addEventListener(Event.ENTER_FRAME,func2);
function func1(e:Event):void {
if (condition()) {
gotoAndStop(2);
}
}
Ici, si condition()
est vraie, le premier auditeur exécutera gotoAndStop()
, mais le second écouteur sera toujours exécuté et si celui-ci référence des objets sur la trame, une erreur 1009 sera générée. La solution consiste à éviter plusieurs écouteurs sur un même événement, dans un seul objet, il est préférable d'avoir un écouteur qui gère toutes les situations sur cet événement et peut se terminer correctement si un changement de trame est nécessaire.