{"id":8916,"date":"2012-05-18T16:02:35","date_gmt":"2012-05-18T14:02:35","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=8916"},"modified":"2012-05-22T16:01:11","modified_gmt":"2012-05-22T14:01:11","slug":"corso-di-sopravvivenza-ai-crash-come-fare-il-debug-delle-applicazioni-ios-iphone-e-ipad","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/corso-di-sopravvivenza-ai-crash-come-fare-il-debug-delle-applicazioni-ios-iphone-e-ipad\/","title":{"rendered":"Corso di sopravvivenza ai crash: come fare il debug delle applicazioni iOS (iPhone e iPad)"},"content":{"rendered":"<p>Bentrovati in questo breve articolo che illustra i principali strumenti per il debug delle nostre applicazioni per iOS.<br \/>\nNon credo di dover spiegare perch\u00e9 sia necessario fare il debug, quando scriviamo il codice siamo tutti convinti che sia corretto, poi proviamo l&#8217;applicazione e BANG&#8230; si chiude inaspettatamente&#8230;allora che fare? Mettersi seduti comodi e sereni e analizzare bene il codice che abbiamo scritto alla ricerca dell&#8217;errore. Senza tirare in ballo scuse come &#8220;Sar\u00e0 un bug del sistema operativo&#8230; del compilatore&#8230; della libreria&#8221; perch\u00e9, sebbene anche l\u00ec siano presenti dei bug \u00e8 molto (ma molto) pi\u00f9 probabile che il bug sia proprio nel codice che abbiamo scritto, che sembrava corretto, ma che invece non lo era affatto.<!--more--><\/p>\n<p>Fortunatamente Apple  ha messo a disposizione dei programmatori un nutrito set di strumenti utili per effettuare il debug delle applicazioni, e altri ancora sono invece utili per effettuare il tuning delle prestazioni. Quindi niente pi\u00f9 scuse e vediamo in dettaglio come scovare i bug nei nostri programmi.<\/p>\n<p>Per fare qualche esempio ho preparato un progetto davvero pieno di bug, potete scaricarlo da <a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/CrashTest.zip\" target=\"_blank\">QUESTO indirizzo<\/a>.<\/p>\n<p>Scaricate quindi ed eseguite il progetto sul simulatore: si presenter\u00e0 con questa minacciosa tastiera il cui unico scopo \u00e8 quello di far andare in crash l&#8217;applicazione ogni volta in un modo diverso&#8230; da questo punto di vista potremmo dire che l&#8217;applicazione non ha BUG&#8230;perch\u00e9 fa proprio quello per cui \u00e8 stata pensata! \ud83d\ude42<\/p>\n<h4>Primo bug<\/h4>\n<p>Una volta eseguito il progetto provate a cliccare sul primo pulsante, il pulsante &#8220;Unknow Selector&#8221; vedrete che l&#8217;applicazione \u00e8 andata in crash e vi verr\u00e0 mostrata questa schermata:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-01.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-01.jpg\" alt=\"debug-di-applicazioni-ios-iphone-ipad-01\" title=\"debug-di-applicazioni-ios-iphone-ipad-01\" width=\"550\" height=\"322\" class=\"aligncenter size-full wp-image-8920\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-01.jpg 1352w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-01-300x175.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-01-1024x599.jpg 1024w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Guardiamo bene questa schermata, nella parte sinistra possiamo vedere la lista dei thread che erano in esecuzione al momento del crash, in questo caso erano 4 ed il primo (il cosiddetto &#8220;main thread&#8221;) \u00e8 andato  in crash.<\/p>\n<p>Quello che si vede  espandendo il simbolo del thread \u00e8 lo <strong>stack trace<\/strong>, viene mostrato in ordine lo stack del thread, con i nomi dei metodi e delle funzioni.<\/p>\n<p>Devo divagare per i meno esperti&#8230; Che cos&#8217;\u00e8 lo stack? Vi sarete resi conto che programmando si possono annidare chiamate di funzioni dentro altre, no? Ad esempio un codice come questo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n[self.label setText:[NSString stringWithFormat:@\"%@ - %d\", [[stringa stringByTrimmingCharactersInSet: [NSCharacterSet whiteSpaceAndNewlineCharacterSet]];\r\n], 40 + 2]];\r\n<\/pre>\n<p>Come fa il computer ad eseguire questa operazione? Se provate a farla a mente vi renderete conto che procederete a step, partendo dal setTex: ma vi fermerete subito in quanto per eseguire il setText avrete bisogno del parametro, ma per calcolare il parametro dovrete calcolare stringWithFormat, per calcolare stringWithFormat vi servir\u00e0 calcolare 40 + 2,  stringByTrimmingCharactersInSet e whiteSpaceAndNewlineCharacterSet.<\/p>\n<p>Insomma, \u00e8 necessario quindi un meccanismo che permetta di lasciare in asso l&#8217;esecuzione di una funzione per eseguire un&#8217;altra il cui risultato serve alla prima operazione&#8230; questo problema i progettisti l&#8217;hanno risolto con lo stack.<br \/>\nLe operazioni vengono inserite in una pila (stack in inglese) e vengono rimosse appena vengono completate cos\u00ec che si possa passare alla operazione sottostante.<br \/>\nSemplificando, per l&#8217;operazione descritta precedentemente potremmo avere uno stack come questo:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-02.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-02.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-02\" title=\"debug-di-applicazioni-ios-iphone-ipad-02\" width=\"225\" height=\"219\" class=\"aligncenter size-full wp-image-8921\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Tornando quindi al nostro debugger, sulla sinistra vediamo lo stack delle chiamate, in questo caso le nostre chiamate non sono pi\u00f9 presenti perch\u00e9 sono termiante e vediamo solo le chiamate di sistema.<br \/>\nNella finestra principale dove solitamente scriviamo il codice vediamo che c&#8217;\u00e8 una riga evidenziata con il messaggio &#8220;<strong>Thread 1: signal SIGABRT<\/strong>&#8221; (vedi: <a href=\"http:\/\/en.wikipedia.org\/wiki\/SIGABRT\" target=\"_blank\">http:\/\/en.wikipedia.org\/wiki\/SIGABRT<\/a>).<\/p>\n<p>Ma perch\u00e9 viene evidenziata questa riga e che nesso ha con il nostro bug?<\/p>\n<p>La riposta \u00e8 che poich\u00e9 l&#8217;eccezione non \u00e8 stata correttamente gestita da nessuna delle nostre classi allora \u00e8 risalita via via nella gerarchia ed \u00e8 arrivata al top e se anche l\u00ec nessuno la gestisce ecco che l&#8217;applicazione crassa.<br \/>\nVedremo nel prossimo esempio come gestire localmente un&#8217;eccezione in modo che non risalga e faccia crashare il programma.<\/p>\n<p>Nella parte bassa dello schermo vediamo la schermata che fornisce maggiori dettagli, vediamo infatti che LLDB (il debugger di XCode sostituto del buon vecchio GDB) ha stampato per noi alcuni messaggi, in particolare il secondo recita:<\/p>\n<p><strong>*** Terminating app due to uncaught exception &#8216;NSInvalidArgumentException&#8217;, reason: &#8216;-[UIRoundedRectButton setText:]: unrecognized selector sent to instance 0x6a32a40&#8217;<\/strong><\/p>\n<p>Ci sta dicendo, anche piuttosto chiaramente, che abbiamo provato a richiamare il metodo setText: su un oggetto di tipo UIRoundedRectButton che non ha affatto questo metodo e richiamare un metodo su un oggetto che non lo implementa \u00e8 un&#8217;eccezione che fa crashare il programma.<\/p>\n<p>Capita la causa non ci resta che risolvere il problema, e per risolvere il problema bisognerebbe trovare la riga di codice dove abbiamo richiamato il metodo setTex&#8230; cosa non facile su un progetto enorme.<\/p>\n<p>Dobbiamo trovare una soluzione per intercettare le eccezioni non appena queste vengono sollevate, senza attendere che arrivino in cima, in questo modo potremmo vedere la riga di codice che ha generato l&#8217;eccezione e non il file main.c<\/p>\n<p>Questo fortunatamente \u00e8 possibile farlo ed \u00e8 anche piuttosto semplice, dobbiamo aprire la scheda della gestione dei breakpoint:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-03.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-03.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-03\" title=\"debug-di-applicazioni-ios-iphone-ipad-03\" width=\"237\" height=\"30\" class=\"aligncenter size-full wp-image-8922\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Cliccare sul tasto &#8220;+&#8221; in basso a sinistra, quindi su &#8220;Add Exception Breakpoint&#8221;:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-04.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-04.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-04\" title=\"debug-di-applicazioni-ios-iphone-ipad-04\" width=\"256\" height=\"82\" class=\"aligncenter size-full wp-image-8923\" \/><\/a><br \/>\n<\/center><\/p>\n<p>e infine su &#8220;done&#8221; assicurandosi di aver selezionato &#8220;All&#8221; per la voce Exception e &#8220;On Throw&#8221; per la voce Break. <\/p>\n<p>Cosa abbiamo fatto? In pratica abbiamo aggiunto un breakpoit, che sar\u00e0 attivato non appena viene sollevata un&#8217;eccezione. Ri-eseguiamo il codice e pigiamo sempre il primo bottone, vedremo questa schermata:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05.jpg\" alt=\"debug-di-applicazioni-ios-iphone-ipad-05\" title=\"debug-di-applicazioni-ios-iphone-ipad-05\" width=\"550\" height=\"334\" class=\"aligncenter size-full wp-image-8924\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05.jpg 1438w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05-300x182.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05-1024x621.jpg 1024w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Ottimo, il debugger si \u00e8 proprio fermato nella riga di codice incriminata! Infatti notiamo subito che viene richiamato il metodo setText: sul sender, ma il sender \u00e8 un pulsante quindi il metodo corretto \u00e8 <strong>setTitle:forState:<\/strong><\/p>\n<p>Modifichiamo quindi il metodo in questo modo e rieseguiamo il codice, vedremo che l&#8217;errore sar\u00e0 sparito:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (IBAction)unknowSelectorErrorTest:(id)sender {\r\n    [sender setTitle:@\"Hello devApp\" forState:UIControlStateNormal];\r\n}\r\n<\/pre>\n<p>Come abbiamo detto c&#8217;\u00e8 un modo per evitare che l&#8217;eccezione risalga la gerarchia del nostro programma e lo porti al crash, come si pu\u00f2 fare?<\/p>\n<p>A voler approfondire l&#8217;argomento ci starebbe tutto un intero articolo (o pi\u00f9 di uno). \u00c8 gi\u00e0 tanta la teoria che sta dietro il design delle classi di un&#8217;applicazione e, se mettiamo in  conto anche cosa dovrebbe rendersi conto che una classe ha riscontrato un errore, la faccenda si complica ancora di pi\u00f9.<\/p>\n<p>Quello che dobbiamo fare \u00e8 in pratica dire al nostro programma &#8220;ehi, prova ad eseguire questo codice, se qualcosa va storto chiamami. Ah, poi quando finisci, in ogni caso, fai queste operazioni qui&#8230;&#8221; (si lo so che tendo ad antropomorfizzare i miei programmi&#8230; lasciatemi nella mia follia) ma come si fa?<\/p>\n<p>Semplicemente usando il costrutto:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n@try {\r\n        <#statements#>\r\n    }\r\n    @catch (NSException *exception) {\r\n        <#handler#>\r\n    }\r\n    @finally {\r\n        <#statements#>\r\n    }\r\n<\/pre>\n<p>Il primo blocco contiene le operazioni da eseguire e che sono potenzialmente dannose, il blocco @catch &#8220;cattura&#8221; l&#8217;errore che \u00e8 stato eventualmente sollevato dalle righe precedenti, infine il terzo blocco esegue delle istruzioni indipendentemente se ci siano stati o meno degli errori.<\/p>\n<p>Se provate a guardare il codice del metodo <strong>unknowSelectorErrorManaged<\/strong> vedrete che in pratica \u00e8 lo stesso codice &#8220;dannoso&#8221; del metodo precedente, ma stavolta pu\u00f2 essere eseguito senza far crashare l&#8217;intera applicazione perch\u00e9 viene gestito localmente:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(IBAction)unknowSelectorErrorManaged:(id)sender {\r\n    @try {\r\n        [sender setText:@\"Hello devAPP\"];\r\n    }\r\n    @catch (NSException *exception) {\r\n        NSLog(@\"oh snap! %@\", [exception description]);\r\n    }\r\n    @finally {\r\n        NSLog(@\"Operazione terminata\");\r\n    }\r\n}\r\n<\/pre>\n<p>Questo \u00e8 il messaggio di log:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05b.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05b.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-05b\" title=\"debug-di-applicazioni-ios-iphone-ipad-05b\" width=\"550\" height=\"42\" class=\"aligncenter size-full wp-image-8946\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05b.png 728w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-05b-300x23.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<h4>Secondo bug<\/h4>\n<p>Vediamo adesso come lo stack ci pu\u00f2 aiutare a trovare la fonte di un errore, eseguiamo il programma e clicchiamo sul terzo pulsante &#8220;Test stack&#8221;, il programma crasher\u00e0 e verr\u00e0 mostrata questa schermata:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-06.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-06.jpg\" alt=\"debug-di-applicazioni-ios-iphone-ipad-06\" title=\"debug-di-applicazioni-ios-iphone-ipad-06\" width=\"550\" height=\"334\" class=\"aligncenter size-full wp-image-8925\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-06.jpg 1438w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-06-300x182.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-06-1024x621.jpg 1024w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Il programma si ferma (grazie al breakpoint) nella riga che ha scatenato l&#8217;errore ma se vogliamo avere maggiori informazioni ecco che questa volta ci viene in aiuto lo stack trace:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-07.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-07.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-07\" title=\"debug-di-applicazioni-ios-iphone-ipad-07\" width=\"409\" height=\"191\" class=\"aligncenter size-full wp-image-8926\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-07.png 409w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-07-300x140.png 300w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Si possono vedere le tre chiamate effettuate del nostro codice, l&#8217;ultima \u00e8 selezionata perch\u00e9 \u00e8 poprio l\u00ec che \u00e8 avvenuto l&#8217;errore.<\/p>\n<p>Cliccando sulle altre righe possiamo andare ad ispezionare il codice chiamante, cos\u00ec da renderci conto di qual \u00e8 lo stato attuale del programma e da dove arrivano i parametri che la nostra funzione sta usando.<br \/>\nIn questo caso ci rendiamo conto subito guardano il punto 3 che l&#8217;array che viene passato come parametro ha due sole voci, di conseguenza gli indici corretti sono 0 e 1 e non 1 e 2 come ho scritto&#8230; correggiamo l&#8217;immondo errore e verifichiamo che tutto sia corretto.<\/p>\n<h4>Terzo bug<\/h4>\n<p>Passiamo adesso al terzo errore. Se clicchiamo sul pulsante &#8220;Breakpoint condizionale ()&#8221; vedremo che tra parentesi appare un numero progressivo che fa da conta-clik&#8230; per\u00f2 c&#8217;\u00e8 un problema: se proviamo a cliccare fino a 25 appare un numero stranissimo:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-08.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-08.jpg\" alt=\"debug-di-applicazioni-ios-iphone-ipad-08\" title=\"debug-di-applicazioni-ios-iphone-ipad-08\" width=\"396\" height=\"744\" class=\"aligncenter size-full wp-image-8945\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-08.jpg 396w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-08-159x300.jpg 159w\" sizes=\"auto, (max-width: 396px) 100vw, 396px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>In questo caso non si tratta di un&#8217;eccezione, il programma continua a funzionare solo che non si comporta come dovrebbe. Non ci resta che piazzare un breakpoint all&#8217;interno del metodo richiamatto dal pulsante per verificare cosa succede.<br \/>\nPer piazzare un breakpoint clicchiamo nella barra di fianco al codice, nella riga in cui viene incrementata la variabile counter:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-09.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-09.jpg\" alt=\"debug-di-applicazioni-ios-iphone-ipad-09\" title=\"debug-di-applicazioni-ios-iphone-ipad-09\" width=\"550\" height=\"129\" class=\"aligncenter size-full wp-image-8928\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-09.jpg 941w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-09-300x70.jpg 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Cos\u00ec facendo l&#8217;esecuzione del programma viene bloccata ogni volta che si entra in quel metodo, ma questo pu\u00f2 non essere molto comodo, come in questo caso in cui saremo costretti a far bloccare l&#8217;esecuzione 24 volte prima di arrivare al momento in cui vogliamo capire che cosa succede. Clicchiamo allora con il desto sul breakpoint e scegliamo &#8220;Edit breakpoint&#8221;:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-10.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-10.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-10\" title=\"debug-di-applicazioni-ios-iphone-ipad-10\" width=\"303\" height=\"134\" class=\"aligncenter size-full wp-image-8929\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-10.png 303w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-10-300x132.png 300w\" sizes=\"auto, (max-width: 303px) 100vw, 303px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>e aggiungiamo la condizione:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-11.png\" alt=\"debug-di-applicazioni-ios-iphone-ipad-11\" title=\"debug-di-applicazioni-ios-iphone-ipad-11\" width=\"504\" height=\"169\" class=\"aligncenter size-full wp-image-8930\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-11.png 504w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/05\/debug-di-applicazioni-ios-iphone-ipad-11-300x100.png 300w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>In questo modo il breakpoint sar\u00e0 attivo solo quando counter varr\u00e0 24 e avremo quindi sicuramente velocizzato tutta l&#8217;operazione.<\/p>\n<p>In particolare eseguendo il debug possiamo vedere che quando counter vale 24 entra in quel brutto <code>if (! ((int)(counter) % (int)(100 \/ 20 * 5)) )<\/code> assegnando poi a counter il valore si sqrt(-1)&#8230; nel dubbio che quella riga sia stata scritta sotto l&#8217;effetto dell&#8217;alcol la cancelliamo e correggiamo il codice.<\/p>\n<h4>Quarto bug?<\/h4>\n<p>Prima si salutarci lancio un test: <strong>nel programma c&#8217;\u00e8 ancora un bug<\/strong>, chi lo trova e lo risolve posti la sua idea nei commenti!<\/p>\n<p>Si conclude qui questo breve articolo sul debug con iOS, per qualsiasi domanda non esitate a chiedere sul <a href=\"http:\/\/forum.devapp.it\" target=\"_blank\">nostro forum<\/a>.<\/p>\n<p>Alla prossima!<br \/>\nIgnazioc<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bentrovati in questo breve articolo che illustra i principali strumenti per il debug delle nostre applicazioni per&#8230;<\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[8],"tags":[1095,1099,1097,1096,1100,1098],"class_list":["post-8916","post","type-post","status-publish","format-standard","hentry","category-guide-varie","tag-debug-applicazioni-ios","tag-exception-xcode","tag-nsinvalidargumentexception","tag-signal-sigabrt","tag-stack-trace-ios","tag-usare-i-breakpoint-xcode"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/8916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=8916"}],"version-history":[{"count":22,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/8916\/revisions"}],"predecessor-version":[{"id":8983,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/8916\/revisions\/8983"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=8916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=8916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=8916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}