Cómo detectar métodos no utilizados y #importar en Objective-C

99

Después de trabajar mucho tiempo en una aplicación de iPhone, me di cuenta de que mi código está bastante sucio, contiene varios #import y métodos que no se llaman ni son útiles en absoluto.

Me gustaría saber si hay alguna directiva de compilación o forma de detectar esas líneas de código inútiles. ¿Xcode tiene alguna herramienta para detectar esto?

Hectoret
fuente

Respuestas:

66

Xcode le permite (des) verificar la configuración de advertencias específicas del compilador que pueden advertirle de algunos tipos de código no utilizado. (Seleccione el proyecto en la lista de fuentes y Archivo> Obtener información, luego seleccione la pestaña Compilar). Aquí hay algunos (que se muestran para Clang y GCC 4.2 para mí) que pueden ser de interés:

  • Funciones no utilizadas
  • Parámetros no utilizados
  • Valores no utilizados

No veo ninguna opción para detectar importaciones no utilizadas, pero eso es un poco más simple: el enfoque de baja tecnología es solo comentar las declaraciones de importación hasta que obtenga un error / advertencia de compilación.

Los métodos Objective-C no utilizados son mucho más difíciles de detectar que las funciones C no utilizadas porque los mensajes se envían dinámicamente. Una advertencia o error puede indicarle que tiene un problema potencial, pero la falta de uno no garantiza que no tendrá errores de tiempo de ejecución.


Editar: Otra buena forma de detectar métodos (potencialmente) no utilizados es examinar la cobertura del código de las ejecuciones reales. Por lo general, esto se hace en conjunto con las pruebas unitarias automatizadas, pero no tiene por qué ser así.

Esta publicación de blog es una introducción decente a las pruebas unitarias y la cobertura de código usando Xcode. La sección sobre gcov(que solo funciona con código generado por GCC, por cierto) explica cómo hacer que Xcode construya código instrumentado que pueda registrar la frecuencia con la que se ha ejecutado. Si prueba una compilación instrumentada de su aplicación en el simulador, luego ejecuta gcov en ella, puede ver qué código se ejecutó utilizando una herramienta como CoverStory (una GUI bastante simplista) o lcov(scripts de Perl para crear informes HTML) .

Utilizo gcovy lcovpara CHDataStructures.framework y genero informes de cobertura automáticamente después de cada confirmación de SVN. Una vez más, recuerde que no es prudente tratar la cobertura ejecutada como una medida definitiva de qué código está "muerto", pero ciertamente puede ayudar a identificar métodos que puede investigar más a fondo.

Por último, dado que está tratando de eliminar el código muerto, creo que también encontrará interesante esta pregunta SO:

Quinn Taylor
fuente
4
No estoy seguro de cuál es su punto ... El analizador estático puede encontrar muchos problemas, pero si envía un mensaje a una variable escrita como id, o crea un selector para llamar en tiempo de ejecución, el analizador estático no puede garantizar que el código realmente no se utiliza. Si se elimina el código que aún se necesita, ahí es donde obtendría errores de tiempo de ejecución. ¿Me estoy perdiendo de algo?
Quinn Taylor
1
Además, los selectores que se crean basándose en cadenas en tiempo de ejecución son bastante comunes.
dreamlax
1
Por supuesto, hay casos en los que su código dinámico se puede servir mejor si se escribe con más fuerza (es decir, devolver algo en lugar de una identificación). La escritura en tiempo de ejecución es un punto fuerte de la programación Cocoa / Objective-C, pero a veces el mantenimiento y la legibilidad se verían mejor si se pensara más en la escritura sólida.
alesplin
3
Oh, definitivamente estoy de acuerdo. Mi regla general es escribir estáticamente (como lo haría en Java) a menos que realmente necesite escritura dinámica, lo cual es raro pero sucede en ocasiones. Sin embargo, simplemente interactuar con las clases Cocoa (por ejemplo, especificando un delegado) puede resultar en rutas de ejecución y dinamismo difíciles de rastrear. Diablos, cualquier programa con un ciclo de ejecución y varios subprocesos puede ser no trivial ...
Quinn Taylor
39

Appcode tiene una función de inspección de código que encuentra importaciones y código no utilizados.

patrick-fitzgerald
fuente
18
Entonces, ¿quiere decir que deberíamos instalar Appcode solo para esta función?
mayqiyue
Si te es útil, ¡sí!
rmp251
5

Recientemente escribí un script para encontrar #importdeclaraciones no utilizadas (o duplicadas) : https://gist.github.com/Orangenhain/7691314

El script toma un archivo .m de ObjC y comienza a comentar cada #importlínea por turno y ver si el proyecto aún se compila. Tendrá que cambiar BUILD_DIR y BUILD_CMD.

Si está usando un findcomando para permitir que el script se ejecute en varios archivos, asegúrese de usar un BUILD_CMD que realmente use todos esos archivos (o verá un archivo con muchas declaraciones de importación sin usar).

Escribí esto sin saber que AppCode tiene una característica similar, sin embargo, cuando probé AppCode no fue tan completo como este script (pero mucho más rápido [para un proyecto completo]).

Orangenhain
fuente
Funciona solo para duplicados, las importaciones no utilizadas no se eliminan.
Rahul
1

Recientemente, cambié un gran proyecto de Carbon a Cocoa. Al final de esto, había bastantes archivos huérfanos que ya no se usaban. Escribí un guión para encontrarlos que esencialmente hicieron esto:

Asegúrese de que la fuente esté registrada en subversion (es decir, limpia) Asegúrese de que actualmente se compila sin errores (es decir, xcodebuild devuelve el estado 0) Luego, para cada archivo fuente en el directorio, vacíe (es decir, elimine el contenido, trunque la longitud) el fuente y el archivo de encabezado, intente una compilación, si falla, revertir los archivos, de lo contrario, déjelos vacíos.

Después de ejecutar esto, revierta y luego elimine todos los archivos vacíos, compile y luego elimine todas las #importaciones con errores.

También debo agregar, debe evitar los archivos a los que se hace referencia desde archivos .xib o .sdef, y puede haber otros casos de enlaces dinámicos, pero aún puede brindarle una buena pista sobre lo que se puede eliminar.

Se puede utilizar la misma técnica para ver qué #importaciones se pueden eliminar; en lugar de truncar el archivo, elimine cada #importación del archivo y vea si la compilación falla.

Peter N Lewis
fuente