Ad un certo punto o in un altro, ti imbatterai in un incidente causato da EXC_BAD_ACCESS. In questo suggerimento rapido, imparerai cos'è EXC_BAD_ACCESS e da cosa è causato. Vi fornirò anche alcuni suggerimenti per correggere i bug causati da EXC_BAD_ACCESS.
Una volta compresa la causa sottostante di EXC_BAD_ACCESS, capirai meglio il suo nome criptico. C'è una spiegazione semplice e una spiegazione più tecnica. Iniziamo con la semplice spiegazione prima.
Ogni volta che incontri EXC_BAD_ACCESS, significa che stai inviando un messaggio a un oggetto che è già stato rilasciato. Questo è lo scenario più comune, ma ci sono delle eccezioni come discuteremo tra un momento.
La spiegazione tecnica è un po 'più complessa. In C e Objective-C, ti occupi costantemente puntatori. Un puntatore non è altro che una variabile che memorizza l'indirizzo di memoria di un'altra variabile. Quando si invia un messaggio a un oggetto, il puntatore che punta all'oggetto che si sta inviando il messaggio deve essere Dereferenced. Ciò significa che si prende l'indirizzo di memoria puntato dal puntatore e si accede al valore di quel blocco di memoria.
Quando quel blocco di memoria non è più mappato per la tua applicazione o, in altre parole, quel blocco di memoria non viene usato per quello che pensi sia usato, non è più possibile accedere a quel pezzo di memoria. Quando ciò accade, il kernel invia un'eccezione (EXC), a indicare che l'applicazione non può accedere a quel blocco di memoria (CATTIVO ACCESSO).
In sintesi, quando si esegue EXC_BAD_ACCESS, significa che si tenta di inviare un messaggio a un blocco di memoria che non può eseguire quel messaggio.
In alcuni casi, tuttavia, EXC_BAD_ACCESS è causato da un puntatore danneggiato. Ogni volta che l'applicazione tenta di dereferenziare un puntatore danneggiato, viene generata un'eccezione dal kernel.
Il debug di EXC_BAD_ACCESS può essere complicato e frustrante. Tuttavia, ora che EXC_BAD_ACCESS non è più un enigma per te, dovrebbe essere meno scoraggiante.
La prima cosa che devi capire è che la tua applicazione non si blocca necessariamente nel momento in cui il blocco di memoria non è più accessibile dalla tua applicazione. Questo è ciò che spesso rende difficile il debug di EXC_BAD_ACCESS.
Lo stesso vale per i puntatori corrotti. La tua applicazione non si bloccherà perché un puntatore è corrotto. Inoltre, non si blocca se si passa un puntatore danneggiato nella propria applicazione. Quando l'applicazione tenta di dereferenziare il puntatore danneggiato, tuttavia, la cosa non funziona.
Mentre gli zombie hanno guadagnato popolarità negli ultimi anni, sono stati in giro per Xcode per più di un decennio. Il nome zombie potrebbe sembrare un po 'drammatico, ma in realtà è un ottimo nome per la funzione che ci aiuterà a eseguire il debug di EXC_BAD_ACCESS. Lascia che ti spieghi come funziona.
In Xcode, puoi abilitare gli oggetti zombi, il che significa che gli oggetti deallocati sono tenuti in giro come zombi. In altre parole, gli oggetti deallocati sono mantenuti in vita per scopi di debug. Non c'è magia coinvolta. Se si invia un messaggio a un oggetto zombi, l'applicazione si bloccherà ancora a causa di EXC_BAD_ACCESS.
Perché è utile? Ciò che rende difficile eseguire il debug di EXC_BAD_ACCESS è che non si sa a quale oggetto la propria applicazione stava tentando di accedere. Gli oggetti zombi risolvono questo problema in molti casi. Mantenendo vivi gli oggetti deallocati, Xcode può dirti a quale oggetto stavi cercando di accedere, rendendo la ricerca del problema molto più facile.
Abilitare gli zombi in Xcode è molto semplice. Si noti che questo può variare a seconda della versione di Xcode che si sta utilizzando. Il seguente approccio si applica a Xcode 6 e 7. Fare clic sullo schema attivo in alto a sinistra e selezionare Modifica schema.
Selezionare Correre a sinistra e apri il Diagnostica scheda in alto. Per abilitare gli oggetti zombi, seleziona la casella di controllo Abilita oggetti zombi.
Se ora esegui EXC_BAD_ACCESS, l'output nella Console di Xcode ti darà un'idea migliore di dove iniziare la ricerca. Dai un'occhiata al seguente esempio di output.
2015-08-12 06: 31: 55.501 Debug [2371: 1379247] - [ChildViewController rispondeToSelector:] messaggio inviato all'istanza deallocato 0x17579780
Nell'esempio sopra, Xcode ci sta dicendo che un messaggio di respondsToSelector:
è stato inviato a un oggetto zombi. Tuttavia, l'oggetto zombi non è più un'istanza di ChildViewController
classe. Il blocco di memoria precedentemente assegnato al file ChildViewController
l'istanza non è più mappata per la tua applicazione. Questo dovrebbe darti un'idea abbastanza precisa di quale sia la causa principale del problema.
Sfortunatamente, gli oggetti zombi non saranno in grado di salvare la tua giornata per ogni incidente causato da EXC_BAD_ACCESS. Se gli oggetti zombi non fanno il trucco, allora è il momento per un'analisi corretta.
Se gli oggetti zombi non risolvono il tuo problema, la causa principale potrebbe essere meno banale. In tal caso, è necessario dare un'occhiata più da vicino al codice che viene eseguito quando l'applicazione si arresta in modo anomalo. Questo può essere macchinoso e richiede tempo.
Per aiutarti a trovare problemi nella tua base di codice, puoi chiedere a Xcode di analizzare il tuo codice per aiutarti a trovare le aree problematiche. Nota che Xcode analizza il tuo progetto, il che significa che indicherà ogni potenziale problema che incontra.
Per dire a Xcode di analizzare il tuo progetto, scegli Analizzare da Xcode's Prodotto menu o premere Maiuscole-Comando-B. Richiederà Xcode per qualche istante, ma una volta terminato dovresti vedere un elenco di problemi in Issue Navigator sulla sinistra. I problemi rilevati dall'analisi sono evidenziati in blu.
Quando fai clic su un problema, Xcode ti porta al blocco di codice che richiede la tua attenzione. Nota che Xcode sta solo facendo un suggerimento. In alcuni casi, è possibile che il problema non sia pertinente e non sia necessario correggerlo.
Se non riesci a trovare il bug che causa EXC_BAD_ACCESS, è importante esaminare scrupolosamente ogni problema che Xcode ha trovato durante l'analisi del tuo progetto.
EXC_BAD_ACCESS è una frustrazione comune tra gli sviluppatori ed è qualcosa che è inerente alla gestione manuale della memoria. I problemi legati alla gestione della memoria sono diventati meno frequenti dall'introduzione di ARC (Automatic Reference Counting), ma non sono affatto scomparsi.