Como detectar métodos não utilizados e #import em Objective-C

99

Depois de trabalhar muito tempo em um aplicativo para iPhone, percebi que meu código está bastante sujo, contendo vários #import e métodos que não são chamados ou não são úteis.

Gostaria de saber se existe alguma diretiva de compilador ou maneira de detectar essas linhas de código inúteis. O Xcode tem alguma ferramenta para detectar isso?

Hectoret
fonte

Respostas:

66

O Xcode permite que você (des) verifique as configurações de avisos específicos do compilador que podem alertá-lo sobre alguns tipos de código não utilizado. (Selecione o projeto na lista de origem e Arquivo> Obter informações e, em seguida, selecione a guia Compilar.) Aqui estão alguns (que aparecem para Clang e GCC 4.2 para mim) que podem ser de interesse:

  • Funções não utilizadas
  • Parâmetros não utilizados
  • Valores não utilizados

Não vejo nenhuma opção para detectar importações não utilizadas, mas isso é um pouco mais simples - a abordagem de baixa tecnologia é apenas comentar as instruções de importação até obter um erro / aviso de compilação.

Os métodos Objective-C não utilizados são muito mais difíceis de detectar do que as funções C não utilizadas porque as mensagens são despachadas dinamicamente. Um aviso ou erro pode dizer que você tem um problema potencial, mas a falta de um não garante que você não terá erros de tempo de execução.


Editar: Outra boa maneira de detectar métodos (potencialmente) não utilizados é examinar a cobertura do código de execuções reais. Isso geralmente é feito em conjunto com o teste de unidade automatizado, mas não precisa ser.

Esta postagem do blog é uma introdução decente aos testes de unidade e cobertura de código usando Xcode. A seção sobre gcov(que só funciona com código gerado pelo GCC, aliás) explica como fazer com que o Xcode construa um código instrumentado que possa registrar quantas vezes ele foi executado. Se você pegar uma versão instrumentada de seu aplicativo para dar uma volta no simulador e, em seguida, executar gcov nele, você pode ver qual código foi executado usando uma ferramenta como CoverStory (uma GUI bastante simplista) ou lcov(scripts Perl para criar relatórios HTML) .

Eu uso gcove lcovpara CHDataStructures.framework e auto-gerar relatórios de cobertura após cada confirmação de SVN. Novamente, lembre-se de que não é aconselhável tratar a cobertura executada como uma medida definitiva de qual código está "morto", mas certamente pode ajudar a identificar métodos que você pode investigar mais profundamente.

Por último, já que você está tentando remover o código morto, acho que você também achará esta questão interessante:

Quinn Taylor
fonte
4
Não tenho certeza de qual é o seu ponto ... O analisador estático pode encontrar muitos problemas, mas se você enviar uma mensagem para uma variável digitada como id, ou criar um seletor para chamar em tempo de execução, o analisador estático não pode garantir que o código realmente não é usado. Se o código que ainda é necessário for removido, é aí que você obteria erros de tempo de execução. Estou esquecendo de algo?
Quinn Taylor
1
Além disso, os seletores criados com base em strings em tempo de execução são bastante comuns.
dreamlax,
1
Claro, há casos em que seu código dinâmico pode ser melhor servido por um tipo mais forte (ou seja, retornar algo em vez de um id). A tipagem em tempo de execução é um ponto forte da programação Cocoa / Objective-C, mas às vezes a manutenção e a legibilidade seriam melhor servidas pensando mais sobre tipagem forte.
alesplin,
3
Oh, eu definitivamente concordo. Minha regra é digitar estaticamente (como faria em Java), a menos que eu realmente precise de digitação dinâmica, o que é raro, mas acontece ocasionalmente. No entanto, apenas a interface com as classes Cocoa (por exemplo, especificando um delegado) pode resultar em dinamismo e caminhos de execução difíceis de rastrear. Caramba, qualquer programa com um loop de execução e várias threads pode ser não trivial ...
Quinn Taylor
39

Appcode tem um recurso de inspeção de código que encontra códigos e importações não utilizadas.

patrick-fitzgerald
fonte
18
Então, você quer dizer que devemos instalar o Appcode apenas para esse recurso?
mayqiyue
Se for útil para você, sim!
rmp251
5

Recentemente, escrevi um script para encontrar #importdeclarações não utilizadas (ou duplicadas) : https://gist.github.com/Orangenhain/7691314

O script pega um arquivo ObjC .m e começa a comentar cada #importlinha por vez e ver se o projeto ainda compila. Você terá que alterar BUILD_DIR e BUILD_CMD.

Se você estiver usando um findcomando para permitir que o script seja executado em vários arquivos, certifique-se de usar um BUILD_CMD que realmente use todos esses arquivos (ou você verá um arquivo com muitas instruções de importação não utilizadas).

Escrevi isso sem saber que o AppCode tem um recurso semelhante, no entanto, quando testei o AppCode, não foi tão completo quanto este script (mas muito mais rápido [para um projeto inteiro]).

Orangenhain
fonte
Ele está funcionando apenas para duplicatas; as importações não utilizadas não estão sendo removidas.
Rahul
1

Recentemente, mudei um grande projeto de Carbon para Cocoa. No final disso, havia alguns arquivos órfãos que não eram mais usados. Eu escrevi um script para encontrá-los que essencialmente fizeram isso:

Certifique-se de que o código-fonte esteja todo verificado no subversion (ou seja, limpo) Certifique-se de que ele atualmente seja compilado sem erros (ou seja, xcodebuild retorna o status 0) Então, para cada arquivo-fonte no diretório, vazio (ou seja, remova o conteúdo, trunque o comprimento) o fonte e o arquivo de cabeçalho, tente uma compilação, se falhar, reverta os arquivos, caso contrário, deixe-os vazios.

Depois de executar isso, reverta e exclua todos os arquivos esvaziados, compile e remova todos os #imports com erro.

Devo acrescentar também, você precisa evitar arquivos que são referenciados a partir de arquivos .xib ou .sdef, e pode haver outros casos de vinculação dinâmica, mas ainda pode lhe dar uma boa pista sobre o que pode ser excluído.

A mesma técnica pode ser usada para ver quais #imports podem ser removidos - em vez de truncar o arquivo, remova cada #import no arquivo por vez e veja se a compilação falha.

Peter N Lewis
fonte