Sfat rapid Cum se depanează o eroare AS3 # 1009

Una dintre cele mai frecvente întrebări pe care le văd pe forumuri și primesc de la colegi este modul de depanare a erorii 1009, cunoscută și sub numele de "Null Object Reference Error". Sau, așa cum o numesc, "Eroarea enervantă a țânțarilor din iad"? Creste foarte mult si, din pacate, eroarea in sine nu contine prea multe informatii despre sursa erorii. În acest sfat rapid, vom arunca o privire la pașii pe care îi puteți lua pentru a urmări acest țânțar și pentru a-l răsturna.


Introducere

Această piesă este prima de urmărire la cele mai generale? Fixarea bug-uri în AS3? tutorial. Dacă doriți să înțelegeți mai bine unele dintre tehnicile din acest sfat, vă recomandăm să citiți mai întâi acest lucru.


Pasul 1: Înțelegerea erorii

Este prea rău că Adobe nu (sau nu poate) să furnizeze mai multe informații despre rădăcina acestei erori. Mai întâi de toate, este destul de greu formulat (la fel ca toate erorile lor, dar cu atât mai mult decât majoritatea):

TypeError: Eroare # 1009: Nu se poate accesa o proprietate sau o metodă de referință de obiect nul

Să încercăm să punem acest lucru în termeni zilnici. Eroare 1009 înseamnă că ați încercat să faceți ceva cu o variabilă pe care o presupuneți că are o valoare, dar într-adevăr nu. Flash nu-mi place asta. Nici nu v-ar plăcea; imaginați-vă că ați avut un pahar pe care l-ați presupus că era plin de băutura gustoasă la alegere, dar într-adevăr a fost goală. Luați geamul, așteptând o băutură răcoritoare, dar în schimb simțiți greutatea dezamăgitoare a unui pahar gol. Aceasta este propria ta eroare 1009.

În ActionScript, dacă faceți acest lucru:

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

Flash-ul va fi greu (un termen tehnic pentru "produce o eroare?") Când executați codul. Variabila s poate fi declarată, dar valoarea ei este nul (nu am stabilit niciodată valoarea, tocmai a declarat variabila), așa că sună toUpperCase metoda de pe ea este supărător.

Pentru a fi clar, pentru că s este declarată ca a Şir, compilator nu are nici o problemă cu codul: există o variabilă numită s, e o Şir, și toUpperCase este o metodă validă de apelat Şirs. Eroarea pe care o primim este a run-time eroare, ceea ce înseamnă că vom obține doar atunci când vom rula SWF. Numai atunci când se efectuează logica, ajungem acum să vedem cum se dovedește acest lucru.


Pasul 2: Permiteți depanarea

Ca și în cazul oricărei erori de execuție, uneori este destul de ușor să afli ce se întâmplă fără informații suplimentare. Dar de altădată este util să restrângem acest lucru în continuare. În acest moment, încercați să activați "Permiteți depanarea". Când acest lucru este activat, primiți erori care vă oferă, de asemenea, numere de linie. În mod alternativ, este posibil să puteți debuga filmul? apăsând comanda-Shift-Return / Control-Shift-Enter.

Pentru a face acest lucru, consultați articolul general despre sfaturile de depanare, Fixing Bugs în AS3?

Uneori, acest lucru este de ajuns. Cunoscând linia specifică ar putea fi toate informațiile de care aveți nevoie. Dacă nu, vom săpa puțin mai mult în pasul următor.

Dragul nostru redactor, Michael James Williams, a încapsulat punctul acestui pas într-un limerick, pe care mă bucur să vă prezint acum cu bunăvoința sa:

AS3 eroare one-oh-oh-nine
Nu este niciodată un semn foarte bun.
Nu este nevoie de îngrijorare,
Apăsați Ctrl-Shift-Return
Și va indica cauza (bine, linia).


Pasul 3: Începeți urmărirea

Dacă ați găsit linia infracțională, dar încă nu sunteți sigur ce se întâmplă, alegeți linia. Luați toate variabilele în acea linie și le urmăriți inainte de eroarea.

Deoarece eroarea apare atunci când accesați o proprietate sau apelați o metodă pe o variabilă nulă, pentru a vă acoperi bazele, ar trebui să urmăriți orice variabile și proprietăți care sunt imediat urmate de un punct. De exemplu, luați această linie de cod:

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

Desigur, este o bucată de cod destul de controversată, pentru care nu-mi pot imagina o utilizare practică, dar ar trebui să identificați patru total posibil nul valori care sunt accesate cu punctul:

  • myArray: sunăm Apăsați pe această variabilă
  • someSprite: accesăm etapă proprietate
  • etapă: accesăm alinia proprietate
  • alinia: sunăm toLowerCase metodă

Deci, codul dvs. de depanare poate arăta astfel:

 urmări ("myArray:", myArray); urmări ("someSprite:", someSprite); urmări ("someSprite.stage:", someSprite.stage); urmări ("someSprite.stage.align:", someSprite.stage.align);

Ordinul este important; dacă someSprite este obiectul nul, dar încercați pentru someSprite.stage.align înainte de a testa pentru someSprite, ajungeți la rezultate mai puțin definitive.

Acum, bunul simț, de asemenea, joacă în acest lucru. În exemplul meu, dacă etapă există, atunci alinia va avea cu siguranță o valoare; Etapă are întotdeauna un alinia setare, chiar dacă este valoarea implicită.

De obicei, veți vedea ceva asemănător:

 MyArray: [? chestii în matrice? ] someSprite: [obiect Sprite] someSprite.stage: null Eroare # 1009:? 

Ceea ce ar trebui să vă dau seama de faptul că etapă proprietatea este nul, și acum poți să o rezolvi.


Pasul 4: Găsirea unei soluții

Cea mai ușoară soluție este de a încheia declarația ofensatoare într-un? If? bloc și executați blocul numai dacă variabila în cauză nu este nulă. Deci, presupunând că în exemplul nostru precedent, a fost de fapt etapă asta a fost nul, am putea face ceva de genul acesta:

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

Acest test - dacă (someSprite.stage) - va reveni Adevărat dacă există o valoare (indiferent de valoare) și fals daca este nul. În general, această notație funcționează; puteți folosi întotdeauna dacă (someSprite.stage! = null) daca preferi. Numărdar prezintă o situație puțin diferită. În cazul în care Număr are o valoare de 0, atunci, din punct de vedere tehnic, are o valoare, dar este testată dacă (someNumberThatEqualsZero) va evalua la fals. Pentru Numărs puteți utiliza isNaN () pentru a determina dacă o valoare numerică valabilă este stocată într-o variabilă dată.

În orice caz, această tehnică este o metodă simplă de a evita eroarea. Dacă nu este setată variabila pe care dorim să efectuăm o operație, atunci nu efectuați operația. Dacă nu există băutură gustoasă în geamul nostru, nu ridicați geamul. Destul de simplu.

Dar această abordare este posibilă numai dacă logica este opțională. Dacă este necesară logica, probabil că puteți furniza o valoare implicită variabilei discutabile înainte de operația de eroare. De exemplu, dacă myArray are potențialul de a fi nul, dar este imperativ ca nu este, putem face acest lucru:

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

Acest lucru va verifica mai întâi pentru a vedea dacă este matricea nul. Dacă este, inițializați-o într-o matrice goală (o matrice goală este o valoare validă. Poate fi goală, dar este o matrice și nu nul) înainte de a executa linia controversată de cod. Dacă nu este nul, sări direct la linia controversată de cod. În termeni reali, dacă paharul nostru este gol, umpleți-l cu o băutură gustoasă înainte de ao ridica.

În plus, dacă myArray este o proprietate de instanță a clasei în care rulează această linie de cod, puteți asigura o valoare validă prin inițializarea proprietăților atunci când obiectul inițializează.

Ce se întâmplă dacă este necesară logica, dar variabila în cauză nu este atât de ușor sub controlul nostru? De exemplu, ce se întâmplă dacă linia noastră de coduri este necesară, dar variabila discutabilă este someSprite.stage? Nu putem seta doar etapă proprietate; care este controlat intern DisplayObject și este citit doar pentru noi muritori. Apoi este posibil să aveți nevoie să vă lăsați vicioși și citiți următorul pas.


Pasul 5: Efectuarea unei acțiuni nul etapă

Există probabil un număr infinit de scenarii în care o anumită variabilă sau o proprietate ar putea fi nul. Evident, nu pot să le acoperez pe toate într-un sfat rapid. Există, totuși, o situație specifică care culminează din nou și din nou.

Să presupunem că scrieți un cod care arată astfel:

 clasa publică QuickSprite extinde Sprite funcția publică QuickSprite () stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove);  funcția privată onMove (e: MouseEvent): void var culoare: ColorTransform = new ColorTransform (); color.color = stage.mouseX / stage.stageWidth * 0xFFFFFF; this.transform.colorTransform = culoare; 

Un alt bit controversat de cod (care ar putea provoca convulsii - te consideri avertizat), dar în principiu ideea este că ai spiriduș subclasa și ați setat această clasă pentru un clip pe scenă, utilizând Flash IDE.

Cu toate acestea, decideți că doriți să lucrați cu acestea QuickSpriteprogramat. Deci, încercați acest lucru:

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

Și tu primești eroarea blestemată 1009. De ce? Pentru că în QuickSprite constructor, accesați etapă proprietate (moștenită de la DisplayObject). Atunci când obiectul este creat în întregime cu cod, nu este pe scena la punctul în care rulează acea linie de cod, adică etapă este nul și veți obține eroarea. QuickSprite se adaugă linia următoare, dar nu este destul de curând. Dacă instanța este creată prin tragerea unui simbol din bibliotecă și pe scenă, atunci există puțină magie la locul de muncă în spatele scenei, care asigură că instanța se află pe scenă (adică, etapă proprietatea este setată) în timpul constructorului.

Deci, iată ce faceți: încercați pentru existența unei valori etapă. În funcție de rezultat, puteți fie să rulați imediat codul de setare, fie să configurați un alt ascultător de evenimente pentru momentul în care acesta este QuickSprite se adaugă la scenă. Ceva de genul:

 funcția publică QuickSprite () if (stage) init ();  altceva this.addEventListener (Event.ADDED_TO_STAGE, init);  funcția privată init (e: Event = null) this.removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove); 

Dacă mutăm etapă line la o funcție diferită, și numim această funcție numai când avem o scenă, atunci suntem pregătiți. Dacă etapă există de la început, mergeți mai departe și rulați init () imediat. Dacă nu, vom folosi init () ca funcție de ascultător pentru evenimente ADDED_TO_STAGE, moment în care vom avea o valoare etapă și putem rula codul. Acum putem folosi clasa pentru conectarea la IDE Sprite sau complet programat.

Acest lucru funcționează bine și în clasele de documente. Când rulați un SWF singur, clasa de documente are acces imediat la etapă. Dacă încărcați SWF într-un alt SWF, totuși, codul din stiva de inițializare a clasei de documente este executat înainte ca SWF-ul încărcat să fie adăugat pe ecran. Asemănător etapă-verificarea trucului vă va permite să lucrați cu SWF atât ca piesă independentă, cât și ca un SWF încărcat într-un SWF care conține.


Asta e tot

Vă mulțumim că ați citit acest sfat rapid! Sper că sunteți puțin luminat despre modul în care apare eroarea 1009 și cum puteți să o depanați. Rămâi acordat pentru mai multe sfaturi rapide despre alte erori comune.

Cod