Come Risolvere SIGABRT Errore in Xcode
Scritto da Reinder de Vries, il 6 agosto 2020 in Sviluppo App, iOS
Un minuto di iOS, app funziona bene in Xcode, e la prossima è irrimediabilmente si è schiantato con un criptico SIGABRT errore. Che succede!?
In questo tutorial imparerai:
- Come risolvere l’errore “Signal SIGABRT” in Xcode
- Come utilizzare alcuni degli strumenti di debug in Xcode
- Cosa significa SIGABRT e quali sono le sue cause
- 3 approcci per trovare la causa principale di SIGABRT
Pronto? Andiamo.
- Cosa significa “Thread 1: Signal SIGABRT”?
- Controlla le tue prese
- Controlla lo Stacktrace
- Crea un breakpoint di eccezione
- Ulteriori letture
Cosa significa “Thread 1: Signal SIGABRT”?
L’errore SIGABRT sta per “signal abort”. È un segnale inviato da iOS – il sistema operativo-a un’app in esecuzione, che chiuderà immediatamente l’app a causa di un errore di runtime. Significa essenzialmente che la tua app si è schiantata
Ecco come appare in Xcode:
Nello screenshot vedi alcune cose:
- A sinistra vedi un elenco di thread eseguiti quando l’app si è schiantata. Vedi che il thread che ha causato l’arresto anomalo è il thread principale o “Thread 1”.
- Nell’editor vediamo quel temuto Thread 1: errore signal SIGABRT. Ha evidenziato la riga 12 nell’editor, la definizione della classe di
AppDelegate
. - In basso si vede utile uscita di debug. In questo caso, si ottiene uno stacktrace e un messaggio di errore criptico sul non essere “key value coding-compliant.”
Il problema con l’errore SIGABRT è che è troppo generico. Xcode sta fondamentalmente dicendo: “Guarda, la tua app si è schiantata, questo è tutto ciò che sappiamo.”Nella maggior parte dei casi dell’errore SIGABRT, si ottengono poche informazioni su cosa ha causato l’errore.
Prima di andare avanti, discutiamo alcune idee sbagliate e insidie comuni di SIGABRT:
- L’errore SIGABRT di solito non ha nulla a che fare con la dichiarazione di classe
AppDelegate
, anche se evidenzia quella linea in Xcode. La riga è evidenziata perché è la prima riga di codice della tua app. Non perdere tempo a cercare nella classeAppDelegate
, a meno che tu non sia assolutamente certo che il bug sia lì dentro. - Lo stacktrace è un elenco di chiamate di funzione che portano all’arresto anomalo dell’app. Ciò non significa che la riga di codice che ha causato l’errore sia ovunque nello stacktrace. A volte lo è, ma in altri casi, lo stacktrace porta semplicemente al codice che ha soffocato un valore impostato altrove nel proprio codice.
- Non fissarti cieco su un errore SIGABRT. C’è una causa razionale e logica per l’errore. Probabilmente è un bug nel tuo codice, e non c’è niente di sbagliato in questo. Le app non sono magiche, nessuno è pronto a prenderti e gli insetti non appaiono mai di punto in bianco. Non frustrarti con pensieri come ” Ha funzionato bene ieri!”- lo fa sempre, e ora non lo fa!
Ora che abbiamo stabilito una linea di base, arriviamo alla prima causa di SIGABRT.
Scopri come creare app iOS
Inizia con iOS 14 e Swift 5
Iscriviti al mio corso di sviluppo iOS e scopri come creare fantastiche app iOS 14 con Swift 5 e Xcode 12.
Controlla le tue prese
Una causa comune di “Signal SIGABRT” è un errore di battitura o un bug nelle tue prese. Ecco cosa è successo:
- creazione di un nuovo controller di visualizzazione in Interface Builder, e impostare con un paio di elementi dell’interfaccia utente come pulsanti e le etichette
- È collegato questi elementi dell’interfaccia utente per il codice utilizzando le proprietà della presa, per creare una connessione tra le proprietà di visualizzazione del controller e l’elemento di interfaccia utente Interface Builder
- A un certo punto è cambiato il nome del punto di vendita iniziale proprietà e la vostra app iniziato a schiantarsi con un SIGABRT errore
Quando si utilizza Interface Builder per creare un controller di visualizzazione, l’app si utilizza il file XIB per generare il controller di visualizzazione dell’interfaccia utente quando la tua app viene eseguita (grosso modo). A questo punto collegherà anche le prese da XIB alle proprietà della classe view controller.
Se hai cambiato il nome di una proprietà outlet, la tua app non riesce più a trovarla. E per questo motivo genererà un’eccezione. Ciò che sta causando l’errore SIGABRT, non sta gestendo quell’eccezione.
Ecco come appare in Xcode:
Vedi cosa sta succedendo? La proprietà è chiamata otherButton
, ma l’uscita è ancora chiamata pulsante. A un certo punto abbiamo cambiato la presa-perché il nuovo nome è migliore-e confuso l’applicazione, che ha reso crash.
Nella parte superiore dello stacktrace individuiamo anche un altro indizio:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: ': this class is not key value coding-compliant for the key button.
Cosa significa? L’app ci sta dicendo a questo punto che il controller di visualizzazione non è conforme alla codifica del valore chiave per la chiave button
. Ciò significa che non è possibile trovare la proprietà button
sul controller della vista. E questo è vero, perché l’abbiamo ribattezzato.
iOS utilizza un meccanismo chiamato key value coding per ispezionare le proprietà di un controller di visualizzazione, in modo che possa utilizzare tali proprietà per fare riferimento agli elementi dell’interfaccia utente creati in base a XIB.
Come risolvi il bug a questo punto? È possibile utilizzare 2 approcci:
- Rinominare la proprietà al suo nome originale
- Rimuovere la connessione di uscita in Interface Builder e ricollegarla utilizzando il nuovo nome della proprietà di uscita
Andiamo avanti!
Suggerimento rapido: proprio come un @IBOutlet
modificato può causare ” Thread 1: signal SIGABRT”, così può erroneamente cambiare il nome di un’azione, cioè con @IBAction
, causare l’errore SIGABRT.
Controlla lo Stacktrace
In molti casi Xcode non ti mostrerà alcun messaggio di errore utile per un crash di SIGABRT. Quando ciò accade, è utile conoscere alcuni comandi di debug, come bt
.
Xcode ha un ambiente di debug integrato chiamato LLDB. È quello che vedi nella parte inferiore di Xcode quando viene eseguita l’app, la Console o l’area di output di debug. Vedi spesso i messaggi di debug qui, ma sapevi che puoi anche usarlo per inserire i comandi?
La prossima volta che la tua app si blocca, prova a digitarehelp
in LLDB. In questo modo:
Vedrai che molti dei comandi LLDB corrispondono direttamente alle azioni che puoi eseguire con il debugger, come impostare i punti di interruzione, scavalcare le righe di codice e ispezionare i valori di runtime.
Un comando è particolarmente utile. È possibile digitare bt
per vedere lo stack di chiamate corrente (chiamato anche” backtrace “o”stacktrace”). Questo è un elenco di tutte le funzioni eseguite fino al crash corrente. Questa traccia include in genere la funzione che ha causato un bug.
Qui, controlla lo stacktrace di un tipico errore di Indice fuori intervallo. Nello screenshot qui sotto, abbiamo deliberatamente causato quell’errore ottenendo index 99
da un array che ha solo 4 elementi. Quando l’app si blocca, bt
può dirci quale riga di codice ha causato l’errore.
È possibile individuare le seguenti informazioni nello stacktrace?
- Il codice che causano problemi è alla riga 21 del
ViewController.swift
all’interno delviewDidLoad()
funzione - Si può anche vedere che abbiamo usato il pedice “getter” in
Array
- Prima dell’arresto di un intero mazzo di vista del controller chiamate di funzione sono stati fatti
in Base alle informazioni che abbiamo ottenuto con bt
possiamo trovare la riga incriminata nel nostro codice e risolvere il problema. Xcode ci ha già aiutato in questo caso, evidenziando l’errore nell’editor. In alcuni scenari non avrai tanta fortuna, e quindi può essere utile usare il comando bt
.
Un’ultima cosa: è possibile ispezionare i valori in fase di esecuzione con il comandoprint
. Nello scenario precedente, digitareprint names
avrebbe prodotto questo output:
() $R0 = 4 values { = "Ford" = "Arthur" = "Zaphod" = "Trillian"}
Per la stampa di oggetti complessi, utilizzarepo
. Fantastico!
Tieni presente che uno stacktrace viene eseguito fuori-dentro. La parte inferiore della traccia dello stack mostra le chiamate di funzione di livello superiore, e più in alto lo stack si va, più in profondità le chiamate vanno in. L’ultima, più recente, chiamata di livello più profondo è in cima allo stack.
Fare un’eccezione Breakpoint
È possibile utilizzare i punti di interruzione per interrompere l’esecuzione del codice in una determinata riga. A quel punto è quindi possibile ispezionare i valori e passare attraverso le funzioni.
Un breakpoint di eccezione viene attivato ogni volta che si verifica un’eccezione nel codice. Invece di specificare su quale riga viene attivato il punto di interruzione, si indica al debugger di interrompere l’esecuzione del codice per le eccezioni.
I punti di interruzione delle eccezioni sono utili per ispezionare il codice quando si verifica un’eccezione. Puoi vedere quale riga di codice ha generato l’eccezione e puoi ispezionare i valori nel tuo codice a quel punto. Alcune eccezioni sono causate da bug o stati non validi della tua app, quindi i punti di interruzione delle eccezioni sono utili per trovare e correggere tali bug.
Ecco come è possibile impostare un breakpoint di eccezione:
- Vai al punto di interruzione navigatore in Xcode, utilizzando le schede a sinistra
- fare Clic in basso a sinistra
+
pulsante e scegliere Eccezione di interruzione - Lasciare le impostazioni di default così com’è (anche se sono utili per personalizzare)
- Eseguire il codice
Quando viene generata un’eccezione, l’esecuzione dell’applicazione si blocca. Ora è possibile utilizzare il debugger per ispezionare i valori, scorrere il codice e utilizzare i comandi LLDB. Quando possibile, Xcode ti porterà alla riga di codice che ha causato l’eccezione.
Tieni presente che un’eccezione non blocca necessariamente la tua app! Pertanto, ogni volta che il punto di interruzione dell’eccezione è abilitato e si verifica un’eccezione, l’app viene interrotta. Arrestare il codice con un punto di interruzione non è lo stesso di un crash dell’app, quindi non lasciarti confondere.
Ad esempio, un punto di interruzione dell’eccezione verrà attivato da un’eccezione di vincoli insoddisfatti, ma ciò non bloccherà la tua app. Utilizzare il punto di interruzione dell’eccezione per raccogliere informazioni aggiuntive per l’arresto anomalo di SIGABRT e quindi disabilitarlo una volta risolto il bug (fino a quando non è necessario di nuovo).
Scopri come creare app iOS
Inizia con iOS 14 e Swift 5
Iscriviti al mio corso di sviluppo iOS e scopri come creare fantastiche app iOS 14 con Swift 5 e Xcode 12.
Ulteriori letture
L’errore SIGABRT è abbastanza criptico e può rivelarsi difficile da risolvere. Perché Xcode non può solo fornire messaggi di errore utili? Bene, questa è una buona domanda
La risposta breve è che ci sono così tante parti mobili nello sviluppo di iOS che Xcode non può sempre determinare la causa di un crash. Xcode non sa che hai cambiato erroneamente il nome di una presa. Sa solo che nel collegare la presa, è stato invocato del codice e ciò ha causato un’eccezione.
Ciò significa che vedrai sempre un errore il più vicino possibile alla causa principale. Il meglio che puoi fare è fare un sacco di errori, decifrare un sacco di messaggi di errore, e arrivare a conoscerli meglio. E quello che hai imparato in questo tutorial, è come trovare e risolvere l’errore SIGABRT!
Vuoi saperne di più? Scopri queste risorse:
- Inizia con il debug in Xcode
- Comprendere l’errore “Selettore non riconosciuto inviato all’istanza” in Xcode
- Comprendere l’errore “Inaspettatamente trovato nil durante lo scartamento di un valore opzionale”
- Comprendere l’errore “Uso dell’identificatore non risolto” in Xcode
- Errori off-By-One nella programmazione Swift
- Gestione degli errori in Swift/ul>