Xcode e depuração avançada no LLDB: parte 1

Boa tarde, hoje sugiro que você se familiarize com a tradução de um artigo sobre a depuração de aplicativos iOS usando LLDB.

Uma das partes mais intrigantes da apresentação da WWDC 2018, o Xcode e a depuração avançada no LLDB foram introduzidas pelos engenheiros da Apple. Eles deram algumas dicas úteis sobre como usar pontos de interrupção no Xcode e no depurador de baixo nível (LLDB) para otimizar o processo de depuração de bugs, onde quer que o desenvolvedor os detectasse.

O artigo consiste em três partes, abordaremos os principais pontos mencionados na WWDC. Criei um projeto de demonstração especificamente para entender melhor como usar vários tipos de pontos de interrupção (pontos de interrupção) em conjunto com o LLDB para capturar e depurar bugs em seu aplicativo.

Projeto de demonstração

Criei um projeto de tarefa de modelo que todo desenvolvedor do iOS conheceu de uma maneira ou de outra. É muito importante entender como funciona antes de ler o artigo. Aqui estão as principais funções do projeto demo:

  • Quando aberto, vemos um controlador de exibição de tabela que carrega uma lista de postagens.
  • Ao rolar para baixo, o controlador de exibição de tabela carrega novas postagens.
  • No total, você pode carregar postagens 7 vezes .
  • Você pode atualizar a lista de postagens puxando para baixo usando o controlador de atualização (puxe para baixo para atualizar).
  • Na barra de navegação na parte superior, existem 2 marcadores (marcadores) que mostram quantas postagens foram baixadas (marcações à direita) e quantas vezes o usuário já enviou postagens (marcações à esquerda).

Você pode fazer o download do projeto de demonstração aqui, se preferir o Objective-C.

Se você preferir Swift, então a partir daqui .

Inicie o Xcode e vamos lá!

Erros para corrigir!

Portanto, você se familiarizou com o projeto e provavelmente percebeu os seguintes erros:

  • Ao puxar a mesa para baixo, a atualização não atualiza as postagens.
  • O usuário não recebe nenhuma notificação (usando o controlador de alerta) de que a solicitação HTTP não foi concluída devido a problemas de conexão.
  • Você pode carregar postagens mais de 7 vezes.
  • O indicador esquerdo (rótulo) na barra de navegação, responsável pela contagem do número de downloads, não funciona.

Uma regra importante: até o final deste artigo, você não para o compilador e não reinicia o aplicativo após o primeiro lançamento. Você corrige erros durante a execução do programa.

O poder das equipes de instrução

Vamos ao primeiro bug.

1. Quando você puxa a mesa para baixo, as postagens não são atualizadas.

Como reproduzir o erro:

  • Inicie o aplicativo, as 10 primeiras postagens já estão carregadas.
  • Role para baixo para carregar mais postagens.
  • Role até o início da tabela e arraste-o para baixo para atualizar.
  • As novas postagens não são carregadas e as antigas não desaparecem e o contador de postagens não é redefinido.

A abordagem padrão para corrigir esses erros envolve examinar o que acontece dentro do seletor de método responsável pelo UIRefreshControl da nossa tabela. Vá para o PostsTableViewController na seção de suporte ao controle de atualização de marca pragma . A partir da função setupRefreshControl, podemos concluir que o seletor responsável pela atualização de postagens é a função reloadNewPosts . Vamos adicionar um ponto de interrupção à primeira linha desta função e descobrir o que exatamente está acontecendo aqui. Agora role até o início da tabela e arraste a tela para atualizar.

imagem
Objetivo-c

imagem
Swift

O depurador parou no ponto de interrupção que você definiu. Para um estudo mais aprofundado, clique no botão "pular bloco" do depurador.

imagem
Objetivo-c

imagem
Swift

Agora temos uma compreensão do que está dando errado!

A condição if não é atendida (ou seja, a variável booleana isPullDownToRefreshEnabled está definida como NO) e, como resultado, o código para atualização de postagens é ignorado.

A abordagem padrão envolve a interrupção do compilador, então você precisa definir isPullDownToRefreshEnabled como YES / true e isso resolveria o problema. Mas seria muito mais conveniente primeiro testar nossa hipótese antes de fazer alterações no código e sem precisar parar o compilador. É aqui que os comandos das instruções do depurador acabam sendo muito úteis.

Clique duas vezes no ponto de interrupção instalado ou clique com o botão direito do mouse em "Editar ponto de interrupção" e clique no botão "Adicionar ação". Selecione também o tipo de ação "Comando do depurador".

imagem

Agora precisamos definir a propriedade isPullDownToRefreshEnabled como YES / true. Adicione o seguinte comando ao depurador.

Objetivo-c

expression self.isPullDownToRefreshEnabled = YES 


imagem

Swift

 expression self.isPullDownToRefreshEnabled = true 

imagem

Em seguida, verifique se a caixa de seleção "Continuar automaticamente após avaliar ações" está marcada. Ele é responsável por garantir que o depurador não pare sempre no ponto de interrupção e continue automaticamente a trabalhar com o comando recém-adicionado. Agora role até o início da tabela e arraste para baixo para atualizar.

Voila, as novas postagens carregaram e substituíram as antigas e, portanto, o contador de postagens foi atualizado.

Resolvemos o primeiro problema, pegue sua arma anti-bug, seguimos para o segundo.

2. O usuário não recebe nenhuma notificação (usando o controlador de alerta) de que a solicitação HTTP não foi concluída devido a problemas de conexão.

Como reproduzir o erro:

  • Desconecte a conexão à Internet no seu iPhone / simulador.
  • Role até o início da tabela e arraste para baixo para atualizar.
  • Novas postagens não serão baixadas devido a um erro de conexão à Internet.
  • O usuário não recebe nenhuma notificação de erro.

Vá para o PostsTableViewController na seção Rede de marca pragma . Possui exatamente uma função loadPosts . Ele usa uma instância comum do gerenciador de rede para executar uma solicitação HTTP GET que retorna uma matriz de postagens por meio de um manipulador de conclusão de "sucesso" ou o NSError por um manipulador de conclusão de "falha".

Precisamos adicionar o código ao fechamento "sem êxito" para exibir um controlador de alerta. Se você for para a seção Suporte da marca pragma, verá que já existe uma função presentNetworkFailureAlertController responsável por exibir o controlador de alerta desejado. Tudo o que precisamos fazer é chamar essa função dentro de um fechamento "com falha" no loadPosts .
A maneira tradicional é parar o simulador e adicionar o código desejado. Vamos para o outro lado!

Adicione um ponto de interrupção dentro do fechamento "sem êxito" após a linha

Objetivo-c

 [self updateUIForNetworkCallEnd]; 

Swift

 self.updateUIForNetworkCallEnd() 

Clique duas vezes no ponto de interrupção instalado ou clique com o botão direito do mouse em "Editar ponto de interrupção" e clique no botão "Adicionar ação". Selecione também o tipo de ação "Comando do depurador".

Adicione o seguinte comando ao depurador.

Objetivo-c

 expression [self presentNetworkFailureAlertController] 

imagem

Swift

 expression self.presentNetworkFailureAlertController() 

imagem

Verifique se a caixa de seleção "Continuar automaticamente após avaliar ações" está marcada.
Com a Internet desligada, role até o início da tabela e arraste para baixo para atualizar, ou você pode rolar até o final da tabela e tentar carregar novas postagens. Aqui está o que você verá:

imagem

O que acabamos de fazer é chamado " injetar " o código usando um comando adicionado ao depurador em um ponto de interrupção específico.

Um pequeno resumo

Vamos listar mais uma vez o que podemos fazer com os comandos debugger adicionados ao ponto de interrupção:

  • Opere com um valor de propriedade existente.
  • Adicione uma nova linha de código.

Ambas as tarefas foram realizadas durante a execução do programa. Essencialmente, não precisamos parar o compilador para corrigir erros e reiniciar o aplicativo.

O que vem depois?

Além disso, trago a atenção para a segunda parte do artigo , onde corrigiremos mais erros e descobriremos outro tipo de ponto de interrupção (ponto de interrupção) - o ponto de observação (ponto de observação).

Source: https://habr.com/ru/post/pt431506/


All Articles