Quick Tips: Hvordan feilsøke en AS3 Feil # 1009

Quick Tips: Hvordan feilsøke en AS3 Feil # 1009
4
Del
8
Share < .no> Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie som heter Hvordan fikse bugs i Flash.Fixing Bugs i AS3. IntroductionQuick Tips: Hvordan feilsøke en AS3 Feil # 1063

En av de vanligste spørsmålene jeg se på forum og får fra kolleger er hvordan man skal feilsøke Error 1009, også kjent som "Null Object Reference Error." Eller som jeg kaller det, "Irriterende Mosquito Feil fra helvete". Det dukker opp mye, og dessverre feil i seg selv ikke inneholder mye informasjon om kilden til feilen. I denne rask spiss, vil vi ta en titt på noen trinn du kan ta for å spore opp denne mygg og squash det bra.



Innledning

Dette stykket er første oppfølging til de mer generelle "fikse bugs i AS3" tutorial. Hvis du ønsker å bedre forstå noen av teknikkene i dette tipset, kan det være lurt å lese at i sin helhet første


Trinn 1:. Forstå feil

Det er for ille at Adobe ikke (eller ikke kan) gi mer informasjon om roten av denne feilen. Først av alt, det er heller obtusely formulert (mye som alle sine feil, men dette mer enn de fleste):

Feiltype: Feil # 1 009: Kan ikke en egenskap eller metode for et null objekt referanse Anmeldelser

La oss prøve å sette dette i dagligdagse begreper. Feil 1009 betyr at du har prøvd å gjøre noe med en variabel som du antar har en verdi, men egentlig ikke. Flash ikke liker det. Du ville ikke like det heller; tenk deg at du hadde et glass som du antok var full av velsmakende drikke etter eget valg, men egentlig var tom. Du hente glasset, venter en forfriskende slurk, men du føler det skuffende vekten av et tomt glass i stedet. Det er din egen personlige Error 1009.

I Actionscript, hvis du gjør dette:
Var s: String; trace (s.toUpperCase ());

Flash vil boms hardt (et teknisk begrep for "produsere en feil") når du kjører koden. De variable s kan ha blitt erklært, men verdien er null (vi aldri sett verdien, bare erklært variabelen), så ringer toUpperCase metoden på det er plagsom.

For å være klar, fordi s er erklært som en String, kompilator
tar ingen problem med koden: det er en variabel som heter s, det er en streng, og toUpperCase er en gyldig metode for å ringe på Strings. Feilen vi får er en kjøretids
feil, noe som betyr at vi bare får det når vi kjører SWF. Bare når logikken er utført gjør vi nå får se hvordan dette slår ut


Trinn 2:. Permit Debugging

Som med alle kjøretidsfeil, noen ganger er det ganske lett å fortelle hva som skjer på uten noe ekstra informasjon. Men andre ganger er det nyttig å begrense dette ned ytterligere. På dette punktet, kan du prøve å slå på "Tillat Debugging." Når denne er aktivert, får du feil som også gir deg linje tall. Alternativt kan du være i stand til å "Debug Movie" ved å trykke på Kommando-Skift-retur /Kontroll-Skift-Enter.

For å gjøre dette, se den generelle debugging tips artikkelen "Fikse Bugs i AS3"

Noen ganger er dette nok. Å vite den spesifikke linjen kan være all den informasjonen du trenger. Hvis ikke, vil vi grave litt dypere i neste trinn.

Vår kjære redaktør, Michael James Williams, innkapslet poenget med dette trinnet i en limerick, som jeg er glad for å presentere for dere nå med hans tillatelse:

AS3 feil one-oh-oh-nine
Er aldri et veldig godt tegn.
Ingen grunn til bekymring,
Hit Ctrl-Shift-Return
Og det vil finne årsaken (vel, linjen).


Trinn 3: Begynn Tracing

Hvis du har funnet uakseptable linje, men er fortsatt usikker på hva som skjer, plukke fra hverandre linjen. Ta hver variabel i den linjen og spore dem ut før
feilen.

Fordi feilen kommer ved tilgang til en eiendom eller kalle en metode på en null variabel, for å dekke dine baser du bør spore noen variabler og egenskaper som er umiddelbart etterfulgt av en prikk. For eksempel ta denne linjen med kode:
myArray.push (someSprite.stage.align.toLowerCase ());

Riktignok er det en ganske contrived stykke kode som jeg ikke kan forestille seg en praktisk bruk for, men du bør identifisere fire totalt mulige nullverdier som blir aksessert med dot:

myArray: vi ringer push metoden på denne variabelen

someSprite: vi har tilgang til scenen Eiendommen

scenen: vi har tilgang til sluttar eiendom

align: vi ringer den toLowerCase metoden

Så din debugging koden kan se slik ut:
trace ("myArray:", myArray), trace ("someSprite:", someSprite), trace ("someSprite.stage:", someSprite.stage), trace ("someSprite.stage.align:", someSprite.stage.align );

Bestill er viktig; hvis someSprite er null objekt, men du teste for someSprite.stage.align før testing for someSprite, ender du opp med mindre klare resultater.

Nå spiller sunn fornuft også inn i dette. I mitt eksempel, hvis scenen eksisterer, deretter justere ganske visst vil ha en verdi; Stage har alltid en justere innstillingen, selv om det er standardverdien

Vanligvis vil du se noe som følgende:.
myArray: [... ting i rekken ...] someSprite : [protestere Sprite] someSprite.stage: nullError # 1009: ...

som bør holdepunkt du at scenen eiendommen er null, og nå kan du gå om å fikse det


Trinn 4:. Finding en løsning

Den enkleste løsningen er å bryte opp den fornærmende uttalelse i en "hvis" blokk, og bare kjøre blokken om variabelen i spørsmålet er ikke null. Så, forutsatt at i vår forrige eksempel, det var faktisk scenen som var null, kan vi gjøre noe sånt som dette:
if (someSprite.stage) {myArray.push (someSprite.stage.align.toLowerCase ()); }

Denne testen - if (someSprite.stage) - returnerer true hvis det er en verdi (uavhengig av verdi), og usant om det er null. Generelt denne notasjonen fungerer; du kan alltid bruke if (someSprite.stage! = null) hvis du foretrekker det. Tall presentere en litt annen situasjon, though. Hvis tallet har en verdi på 0, så teknisk sett har en verdi, men testing if (someNumberThatEqualsZero) vil vurdere å falske. For Numbers kan du bruke isNaN () -funksjonen til å avgjøre om en gyldig numerisk verdi blir lagret i en gitt variabel.

I alle fall er denne teknikken en enkel måte å omgå feilen. Hvis variabelen vi ønsker å utføre en operasjon på er ikke satt, så ikke gjør operasjonen. Hvis det ikke er velsmakende drikk i vår glass, ikke plukke opp glasset. Enkelt nok.

Men at tilnærmingen er bare mulig hvis logikken er valgfritt. Hvis logikken er nødvendig, så kanskje du kan gi en standardverdi til tvilsom variabel før feilen-ing drift. For eksempel, hvis myArray har potensial til å være null, men det er viktig at det ikke er det, kan vi gjøre dette: (! MyArray)
hvis {myArray = [];} myArray.push (someSprite.stage.align.toLowerCase ());

Dette vil først sjekke om matrisen er null. Hvis det er, initialisere det til en tom array (en tom array er en gyldig verdi. Det kan være tomt, men det er en matrise, og ikke null) før du kjører contrived linje med kode. Hvis det ikke er null, hopper rett til contrived linje med kode. I det virkelige liv vilkår, hvis våre glass er tom, og fyll den med en velsmakende drikke før du plukker den opp.

I tillegg, hvis myArray er en forekomst tilhører klassen der denne linjen med kode kjøres , kan du ganske sikkert sikre en gyldig verdi ved å initial dine egenskaper når objektet initialiserer.

Hva om logikken er nødvendig, men variabel i spørsmålet er ikke så lett under vår kontroll? For eksempel, hva om vår contrived kodelinje er nødvendig, men tvilsom variabelen er someSprite.stage? Vi kan ikke bare sette scenen eiendom; som er kontrollert internt til Displayobject og er skrivebeskyttet til oss vanlige dødelige. Da må du kanskje få crafty, og lese neste trinn


Trinn 5:. Håndteringen av en null scenen

Det er sannsynligvis et uendelig antall scenarier der en gitt variabel eller eiendom kan være null. Selvfølgelig, jeg kan ikke dekke dem alle i en rask spiss. Det er en spesiell situasjon, men dukker det opp igjen og igjen

La oss si at du skriver noen kode som ser slik ut:.
Public class QuickSprite strekker Sprite {offentlig funksjon QuickSprite () {stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove); } Private funksjon onMove (e: MouseEvent): void {var color: ColorTransform = new ColorTransform (); color.color = stage.mouseX /stage.stageWidth * 0xFFFFFF; this.transform.colorTransform = farge; }}

En annen contrived bit av koden (som kan indusere anfall - anser deg selv advart), men i utgangspunktet ideen er at du har en Sprite underklasse og du setter dette som klassen for et klipp på scenen, ved hjelp av Flash IDE .

Men, du bestemmer deg du ønsker å jobbe med disse QuickSprites programmatisk. Så du prøve dette:
Var qs: QuickSprite = new QuickSprite (); addChild (qs);

Og du får den forbannede Error 1009. Hvorfor? Fordi i QuickSprite konstruktør, får du tilgang scenen eiendom (arvet fra Displayobject). Når objektet er opprettet utelukkende med kode, er det ikke på scenen på det punktet at den linjen med kode kjøres, noe som betyr at scenen er null, og du får feilen. Den QuickSprite blir lagt allerede neste linje, men det er ikke fort nok. Dersom forekomsten er skapt ved å dra et symbol ut av biblioteket og på scenen, så er det en litt magi på jobb bak kulissene som sikrer at forekomsten er på scenen (det er, er scenen eiendom) under konstruktøren

Så her er hva du gjør:. du teste for eksistensen av en verdi for scenen. Avhengig av resultatet, kan du enten kjøre satt opp kode med en gang, eller sette opp en annen hendelse lytteren for når QuickSprite ikke får lagt til scenen. Noe sånt som dette:
offentlig funksjon QuickSprite () {if (scene) {init (); } Else {this.addEventListener (Event.ADDED_TO_STAGE, init); }} privat funksjon init (e: Hendelses = null) {this.removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove);}

Hvis vi flytter scenen linje til en annen funksjon, og bare kalle den funksjonen når vi har en scene, så vi er klar. Hvis scenen finnes fra starten av, gå videre og kjøre init () med en gang. Hvis ikke, vil vi bruke init () som en hendelse lytteren funksjon for ADDED_TO_STAGE, og da vil vi ha en scene verdi og kan kjøre koden. Nå kan vi bruke klassen for enten å koble til IDE Sprite eller helt programmatisk.

Dette fungerer godt i dokument klasser, også. Når du kjører en SWF av seg selv, har dokumentet klassen umiddelbar tilgang til scenen. Hvis du legger i at SWF inn i en annen SWF, men koden i dokumentet klassens initialisering stack blir utført før den lastede SWF legges til skjermen. En lignende scene-sjekking triks vil tillate deg å arbeide med SWF både som frittstående stykke og som en SWF lastet inn en inneholder SWF.


Det er alt

Takk for at du leser denne Quick Tips ! Jeg håper du blir opplyst litt om hvordan Error 1 009 oppstår, og hvordan du kan feilsøke det. Stay tuned for flere raske tips om andre vanlige feil. Anmeldelser



Previous:
Next Page: