• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 1/6/21

Utilisez le débugueur

Dans ce chapitre, je vous propose de résoudre notre erreur ! Et pour cela, nous allons avoir besoin d'investiguer le code !

Dans le chapitre précédent, l'analyse de la pile d'exécution nous a révélé que l'erreur avait lieu dans la fonction updateAllSetsScore. Voici le code de celle-ci :

private func updateAllSetsScore(forPlayer player: Player) {
    for i in 0..<6 {
            if i < match.sets.count {
                    let set = match.sets[i]
                    playerSetScoreLabels[player]![i].text = "\(set.scores[player]!)"
             } else {
                    playerSetScoreLabels[player]![i].text = ""
            }
    }
}

Hmm... Difficile de trouver l'erreur du premier coup d'œil dans cette fonction. Pour nous aider, nous allons utiliser un point d'arrêt !

Les points d'arrêt

Le principe d'un point d'arrêt (breakpoint en anglais) est très simple. Il permet, comme son nom l'indique, d'interrompre l'exécution de notre code à la ligne qui nous intéresse. Nous allons voir dans ce chapitre et dans le suivant que c'est extrêmement pratique pour repérer les problèmes.

Mais pour résoudre notre erreur, nous allons avoir besoin pour l'instant d'un point d'arrêt un peu particulier et très puissant !

Le point d'arrêt d'exception

Le point d'arrêt d'exception (ou exception breakpoint) permet d'interrompre le code dès que le programme rencontre une erreur qui va faire planter l'application.

Pour créer ce point d'arrêt, il faut aller dans le navigateur des points d'arrêt. C'est l'avant-dernier onglet du navigateur (panneau de gauche) :

Mets en évidence l'icône du navigateur de points d'arrêt.

Cet onglet est vide pour le moment, car vous n'avez pas encore créé de points d'arrêt. Pour ajouter notre fameux point d'arrêt d'exception, allez tout en bas de l'interface, cliquez sur le + et choisissez dans la pop-up "Exception Breakpoint..." :

Image de la popup permettant de choisir Exception breakpoint...

Ça y est ! Votre point d'arrêt d'exception est créé et il apparaît dans le navigateur de points d'arrêt :

Image du navigateur de point d'arrêt contenant le nouvellement créé point d'arrêt.

Pour que vous puissiez admirer la puissance de ce point d'arrêt, vous n'avez plus qu'à relancer votre application et vous allez voir l'exécution s'interrompre juste avant notre erreur.

Naviguez dans la pile d'exécution

Le point d'arrêt vous conduit directement jusqu'au fichier et même à la ligne qui pose problème :

Impression d'écran de Xcode

Nous n'avons même pas besoin d'analyser la pile d'exécution. On est directement conduit au bon endroit.

En plus, grâce au point d'arrêt, votre pile d'exécution s'affiche sur la gauche dans le navigateur de débogage et vous pouvez naviguer à l'intérieur !

Le navigateur de débogage
Le navigateur de débogage

Pour cela, il vous suffit de cliquer sur la ligne de votre choix sur la droite dans la pile d'exécution et vous êtes immédiatement conduit à la ligne de code correspondante.

Gif de navigation dans la pile d'exécution.

La vue des variables

Bon c'est bien beau de s'amuser, mais on la résout cette erreur ?

Oui... Mais ne soyez pas rabat-joie non plus :D ! La ligne qui semble poser problème est la suivante :

playerSetScoreLabels[player]![i].text = ""

On débarque un peu dans ce code qu'on ne connaît pas donc pour savoir un peu qui est qui, laissez-moi vous présenter la vue des variables ! Dans la zone de débogage, vous avez deux panneaux. A gauche, c'est la vue des variables et à droite la console que vous connaissez déjà.

Impression d'écran de la vue des variables et de la console.

Cette vue permet de visualiser toutes les variables existantes au point d'arrêt où nous nous trouvons. En l'occurrence, il y a ici :

  • player : c'est le paramètre de la fonction. On voit qu'il est de type Player et vaut one.

  • i : c'est le compteur de la boucle for qui vaut ici 5.

  • self : c'est la classe dans laquelle nous nous trouvons, donc ici ViewController.

On peut déplier self pour inspecter l'état de toutes ses propriétés. Notamment on peut regarder la propriété playerSetScoreLabels qui intervient dans la ligne qui pose problème.

Les variables dans la vue des variables.

On comprend que son type est : [Player: [UILabel]] donc un dictionnaire qui a comme clé un joueur et comme valeur un tableau de labels. Mais le reste n'est pas très lisible !

Afficher les variables dans la console

Heureusement, nous avons une autre option pour voir nos variables et ça se passe juste à côté, dans la console !

Enfin pas tout à fait vide ! On y voit l'inscription (lldb), c'est un Low Level Debugger. C'est un peu comme un terminal, on peut écrire des commandes et l'ordinateur nous répond. On peut lui poser plein de questions pour comprendre l'état de notre application.

Nous allons apprendre une seule commande, mais qui est de loin la plus utile, et elle se nomme sobrement po pour Print Object.

Essayons-la avec notre mystérieuse variable playerSetScoreLabels :

Vue de la console.

La console nous affiche plein de détails sur l'objet et cette fois, c'est assez clair. Il y a deux clés : Player.one et Player.two et chacune contient 5 labels. Si on va un peu plus loin, on peut écrire :

Vue de la console

On a bien un tableau qui contient 5 labels.

Résoudre l'erreur

Maintenant, résumons-nous et je pense qu'on va pouvoir résoudre notre erreur. L'erreur intervient à la ligne suivante :

playerSetScoreLabels[player]![i].text = ""

On sait que ce playerSetScoreLabels[player]! est un tableau de 5 éléments. On essaye donc d'accéder à son élément à l'index i, qui vaut 5. Or le plus grand index d'un tableau de 5 éléments, c'est 4. Donc il n'y a rien à l'index 5 !

Et voilà notre erreur ! Notre boucle va un coup trop loin ! Il nous suffit de réduire l'intervalle d'un cran !

for i in 0..<6 { // <= ici il faut mettre 5 à la place du 6 !
    // [...]
}

Faites la modification, lancez l'application et... ça marche ! Le bug a été éliminé ! Bravo !

En résumé

  • Pour identifier la source des erreurs à l'exécution, je vous suggère de créer un point d'arrêt d'exception qui vous emmène directement à la ligne qui pose problème.

  • Un point d'arrêt permet d'interrompre l'exécution du code et d'inspecter les variables pour identifier un bug.

  • Pour inspecter les variables suite à un arrêt, on peut utiliser la vue des variables, ou la commande po dans la console.

Dans le prochain chapitre, nous allons apprendre à positionner des points d'arrêt manuellement pour naviguer dans la pile d'exécution.

Example of certificate of achievement
Example of certificate of achievement