Hva er EXC_BAD_ACCESS og hvordan du kan debug det

På et eller annet tidspunkt vil du løpe inn i et krasj forårsaket av EXC_BAD_ACCESS. I dette raske tipset lærer du hva EXC_BAD_ACCESS er og hva det er forårsaket av. Jeg vil også gi deg noen tips for å fikse feil som skyldes EXC_BAD_ACCESS.

1. Hva er EXC_BAD_ACCESS?

Når du forstår den underliggende årsaken til EXC_BAD_ACCESS, forstår du bedre det krypterte navnet. Det er en enkel forklaring og en mer teknisk forklaring. La oss starte med den enkle forklaringen først.

Holde det enkelt

Når du støter på EXC_BAD_ACCESS, betyr det at du sender en melding til et objekt som allerede er utgitt. Dette er det vanligste scenariet, men det er unntak som vi diskuterer om et øyeblikk.

Hva det egentlig betyr

Den tekniske forklaringen er litt mer kompleks. I C og Objective-C håndterer du hele tiden pekere. En peker er ikke noe mer enn en variabel som lagrer minnesadressen til en annen variabel. Når du sender en melding til et objekt, må pekeren som peker på objektet du sender meldingen til, være dereferenced. Dette betyr at du tar minnesadressen pekeren peker på og får tilgang til verdien til den aktuelle minnekortet.

Når denne blokkeringen av minne ikke lenger er kartlagt for søknaden din eller, sett annerledes, er ikke denne blokkene av minne brukt til det du tror det er brukt, det er ikke lenger mulig å få tilgang til den minste delen av minnet. Når dette skjer, sender kjernen et unntak (EXC), som indikerer at søknaden din ikke kan få tilgang til denne minnekortet (Dårlig tilgang).

Oppsummert, når du kjører inn i EXC_BAD_ACCESS, betyr det at du prøver å sende en melding til en blokk med minne som ikke kan utføre meldingen.

I noen tilfeller er imidlertid EXC_BAD_ACCESS forårsaket av en korrupt peker. Når søknaden din forsøker å dereferere en korrupt peker, kastes et unntak av kjernen.

2. Feilsøking EXC_BAD_ACCESS

Feilsøking EXC_BAD_ACCESS kan være vanskelig og frustrerende. Men da EXC_BAD_ACCESS ikke lenger er en gåte for deg, bør det være mindre skremmende.

Det første du trenger å forstå er at søknaden din ikke nødvendigvis krasjer det øyeblikket minnebukken ikke lenger er tilgjengelig ved søknaden din. Det gjør det ofte vanskelig å feilsøke EXC_BAD_ACCESS.

Det samme gjelder for korrupte pekere. Din søknad vil ikke krasje fordi en peker gikk korrupte. Det vil heller ikke krasje hvis du sender en korrupt peker rundt i søknaden din. Når din søknad forsøker å dereferre den korrupte pekeren, går det imidlertid galt.

Zombies

Mens zombier har vunnet i popularitet de siste årene, har de vært i Xcode i mer enn et tiår. Navnet zombie kan høres litt dramatisk, men det er faktisk et godt navn for funksjonen som skal hjelpe oss med å feilsøke EXC_BAD_ACCESS. La meg forklare hvordan det fungerer.

I Xcode kan du aktivere zombieobjekter, noe som betyr at deallokerte objekter holdes rundt som zombier. Sett forskjellig, deallokerte objekter holdes levende for feilsøkingsformål. Det er ingen magi involvert. Hvis du sender en melding til et zombieobjekt, vil applikasjonen din fortsatt krasje som følge av EXC_BAD_ACCESS.

Hvorfor er dette nyttig? Det som gjør EXC_BAD_ACCESS vanskelig å feilsøke, er at du ikke vet hvilket objekt søknaden din forsøkte å få tilgang til. Zombieobjekter løser dette problemet i mange tilfeller. Ved å holde deallokerte gjenstandene levende, kan Xcode fortelle deg hvilket objekt du prøvde å få tilgang til, slik at søket etter problemet så mye lettere.

Å aktivere zombier i Xcode er veldig enkelt. Vær oppmerksom på at dette kan variere avhengig av hvilken versjon av Xcode du bruker. Følgende tilnærming gjelder for Xcode 6 og 7. Klikk på aktiv skjema øverst til venstre og velg Rediger skjema.

Å velge Løpe til venstre og åpne diagnostikk fanen øverst. For å aktivere zombieobjekter, merk av i boksen merket Aktiver Zombie Objects.

Hvis du nå kjører inn i EXC_BAD_ACCESS, vil utdataene i Xcode's Console gi deg en mye bedre ide om hvor du skal starte søket. Ta en titt på følgende eksempelutgang.

2015-08-12 06: 31: 55.501 Debug [2371: 1379247] - [ChildViewController respondsToSelector:] melding sendt til deallokert forekomst 0x17579780

I eksemplet ovenfor er Xcode fortelle oss at en melding av respondsToSelector: ble sendt til et zombieobjekt. Imidlertid er zombieobjektet ikke lenger en forekomst av ChildViewController klasse. Blokken av minne som tidligere ble tildelt til ChildViewController forekomst er ikke lenger kartlagt for søknaden din. Dette bør gi deg en ganske god ide om hva årsaken til problemet er.

Dessverre vil zombieobjekter ikke kunne lagre dagen din for hver krasj forårsaket av EXC_BAD_ACCESS. Hvis zombieobjekter ikke gjør trikset, så er det på tide for noen riktig analyse.

Analysere

Hvis zombieobjekter ikke løser problemet ditt, kan grunnårsaken være mindre trivial. I så fall må du se nærmere på koden som blir utført når søknaden krasjer. Dette kan være tungvint og tidkrevende.

For å hjelpe deg med å finne problemer i koden din, kan du be Xcode å analysere koden din for å hjelpe deg med å finne problematiske områder. Merk at Xcode analyserer prosjektet ditt, noe som betyr at det vil peke på alle potensielle problemene det møter.

For å fortelle Xcode å analysere prosjektet, velg Analysere fra Xcode er Produkt meny eller trykk Shift--B Command. Det vil ta Xcode et par øyeblikk, men når det er ferdig, bør du se en liste over problemer i Issue Navigator til venstre. Utgaver funnet av analysen er uthevet i blått.

Når du klikker på et problem, tar Xcode deg til koden med kode som trenger din oppmerksomhet. Merk at Xcode bare gjør et forslag. I noen tilfeller er det mulig at problemet ikke er relevant og ikke trenger å fikse.

Hvis du ikke finner feilen som forårsaker EXC_BAD_ACCESS, er det viktig å nøye undersøke hvert problem Xcode funnet under analysen av prosjektet ditt.

Konklusjon

EXC_BAD_ACCESS er en felles frustrasjon blant utviklere, og det er noe som er knyttet til manuell minnehåndtering. Problemer knyttet til minnehåndtering har blitt mindre hyppige siden innføringen av ARC (Automatic Reference Counting), men de har ikke forsvunnet.