Într-un anumit punct sau altul, veți avea parte de un accident cauzat de EXC_BAD_ACCESS. În acest sfat rapid, veți afla ce este EXC_BAD_ACCESS și de ce este cauzat. De asemenea, vă voi oferi câteva sfaturi pentru a remedia erorile cauzate de EXC_BAD_ACCESS.
După ce înțelegeți cauza principală a programului EXC_BAD_ACCESS, veți înțelege mai bine numele său criptic. Există o explicație simplă și o explicație mai tehnică. Să începem mai întâi cu explicația simplă.
Ori de câte ori întâlniți EXC_BAD_ACCESS, înseamnă că trimiteți un mesaj unui obiect care a fost deja lansat. Acesta este cel mai frecvent scenariu, dar există și excepții pe măsură ce vom discuta într-un moment.
Explicația tehnică este un pic mai complexă. În C și Obiectiv-C, vă ocupați în mod constant indicii. Un pointer nu este altceva decât o variabilă care stochează adresa de memorie a altei variabile. Când trimiteți un mesaj către un obiect, indicatorul care indică obiectul la care trimiteți mesajul trebuie să fie dereferentierea. Aceasta înseamnă că luați adresa de memorie indicată spre pointer și accesați valoarea acelui bloc de memorie.
Atunci când acest bloc de memorie nu mai este mapat pentru aplicația dvs. sau, altfel spus, acest bloc de memorie nu este utilizat pentru ceea ce credeți că este folosit, nu mai este posibil să accesați acea bucată de memorie. Când se întâmplă acest lucru, kernelul trimite o excepție (EXC), indicând faptul că aplicația dvs. nu poate accesa acel bloc de memorie (ACCESUL BAD).
În concluzie, atunci când rulați în EXC_BAD_ACCESS, înseamnă că încercați să trimiteți un mesaj către un bloc de memorie care nu poate executa acel mesaj.
În unele cazuri, cu toate acestea, EXC_BAD_ACCESS este cauzat de un pointer corupt. Ori de câte ori aplicația dvs. încearcă să dereferențeze un pointer corupt, o excepție este aruncată de kernel.
Depanarea EXC_BAD_ACCESS poate fi dificilă și frustrantă. Cu toate acestea, acum că EXC_BAD_ACCESS nu mai este o enigmă pentru dvs., ar trebui să fie mai puțin descurajantă.
Primul lucru pe care trebuie să-l înțelegeți este că aplicația dvs. nu cade neapărat în momentul în care blocul de memorie nu mai este accesibil prin aplicația dvs. Asta face adesea dificila depanarea programului EXC_BAD_ACCESS.
Același lucru este valabil pentru indicii corupți. Cererea dvs. nu se va prăbuși deoarece un indicator a devenit corupt. De asemenea, nu se va prăbuși dacă treceți un pointer corupt în aplicația dvs. Când cererea dvs. încearcă să dereferențe pointerul corupt, totuși, lucrurile merg prost.
În timp ce zombi au câștigat în popularitate în ultimii ani, ei au fost în jurul în Xcode pentru mai mult de un deceniu. Numele zombie poate sună puțin dramatic, dar este de fapt un nume grozav pentru caracteristica care ne va ajuta să depanem EXC_BAD_ACCESS. Permiteți-mi să vă explic cum funcționează.
În Xcode, puteți activa obiecte zombie, ceea ce înseamnă că obiectele deallocated sunt păstrate în jurul valorii de zombi. Altfel, obiectele detasate sunt ținute în viață pentru depanare. Nu există magie implicată. Dacă trimiteți un mesaj către un obiect zombie, aplicația dvs. va continua să se prăbușească ca rezultat al lui EXC_BAD_ACCESS.
De ce este util acest lucru? Ceea ce face ca EXC_BAD_ACCESS să fie greu de depanat este faptul că nu știți ce obiect a încercat să acceseze aplicația. Obiectele zombie rezolvă această problemă în multe cazuri. Prin păstrarea în viață a obiectelor dezalocate, Xcode vă poate spune ce obiect ați încercat să accesați, făcând căutarea problemei mult mai ușor.
Activarea zombiilor în Xcode este foarte ușoară. Rețineți că acest lucru poate diferi în funcție de versiunea Xcode pe care o utilizați. Următoarea abordare este valabilă pentru Xcode 6 și 7. Faceți clic pe schema activă din partea stângă sus și alegeți Editați schema.
Selectați Alerga din stânga și deschideți Diagnostice în partea de sus. Pentru a activa obiecte zombie, bifați căsuța de etichetă Activați obiectele zombie.
Dacă acum rulați în EXC_BAD_ACCESS, ieșirea din Consola Xcode vă va oferi o idee mult mai bună despre locul unde puteți începe căutarea. Uitați-vă la exemplul următor.
2015-08-12 06: 31: 55.501 Debug [2371: 1379247] - mesajul [ChildViewController respondsToSelector:] trimis la instanța deallocated 0x17579780
În exemplul de mai sus, Xcode ne spune că un mesaj de respondsToSelector:
a fost trimis la un obiect zombie. Cu toate acestea, obiectul zombie nu mai este o instanță a ChildViewController
clasă. Blocul de memorie care a fost anterior alocat ChildViewController
instanța nu mai este mapată pentru aplicația dvs. Acest lucru ar trebui să vă dau o idee destul de bună despre cauza principală a problemei.
Din păcate, obiectele zombie nu vă vor putea salva ziua pentru fiecare accident cauzat de EXC_BAD_ACCESS. Dacă obiectele zombie nu fac truc, atunci este timpul pentru o analiză corectă.
Dacă obiectele zombie nu vă rezolvă problema, atunci cauza rădăcină poate fi mai puțin banală. În acest caz, trebuie să examinați mai atent codul care se execută atunci când aplicația dvs. se blochează. Acest lucru poate fi greoaie și consumatoare de timp.
Pentru a vă ajuta să găsiți probleme în baza de cod, puteți cere Xcode să vă analizeze codul pentru a vă ajuta să găsiți zone problematice. Rețineți că Xcode analizează proiectul dvs., ceea ce înseamnă că acesta va evidenția orice problemă potențială pe care o întâmpină.
Pentru a le spune Xcode să analizeze proiectul, alegeți A analiza din Xcode Produs meniu sau apăsați Shift-Command-B. Acesta va lua Xcode câteva momente, dar când este terminat ar trebui să vedeți o listă de probleme în Eliberați Navigator pe stanga. Problemele identificate de analiză sunt evidențiate în albastru.
Când faceți clic pe o problemă, Xcode vă duce la blocul de cod care necesită atenția dvs. Rețineți că Xcode face doar o sugestie. În unele cazuri, este posibil ca problema să nu fie relevantă și nu necesită reparații.
Dacă nu puteți găsi bug-ul care provoacă EXC_BAD_ACCESS, atunci este important să examinați cu atenție fiecare problemă Xcode găsită în timpul analizei proiectului dvs..
EXC_BAD_ACCESS este o frustrare obișnuită în rândul dezvoltatorilor și este ceva inerent pentru gestionarea manuală a memoriei. Problemele legate de gestionarea memoriei au devenit mai puțin frecvente de la introducerea ARC (Automatic Counting Counting), dar în nici un caz nu au dispărut.