Come rilevare metodi inutilizzati e #import in Objective-C


100

Dopo aver lavorato a lungo su un'app per iPhone, mi sono reso conto che il mio codice è piuttosto sporco, contenente diversi #import e metodi che non vengono chiamati o non sono affatto utili.

Vorrei sapere se esiste una direttiva del compilatore o un modo per rilevare quelle righe di codice inutili. Xcode ha uno strumento per rilevarlo?

Risposte:


66

Xcode ti consente di (des) controllare le impostazioni per avvisi specifici del compilatore che possono avvisarti di alcuni tipi di codice inutilizzato. (Seleziona il progetto nell'elenco sorgente e File> Ottieni informazioni, quindi seleziona la scheda Crea.) Eccone alcuni (che per me vengono visualizzati per Clang e GCC 4.2) che potrebbero interessarti:

  • Funzioni inutilizzate
  • Parametri inutilizzati
  • Valori inutilizzati

Non vedo alcuna opzione per rilevare le importazioni inutilizzate, ma è un po 'più semplice: l'approccio a bassa tecnologia consiste semplicemente nel commentare le istruzioni di importazione fino a quando non si ottiene un errore / avviso di compilazione.

I metodi Objective-C inutilizzati sono molto più difficili da rilevare rispetto alle funzioni C inutilizzate perché i messaggi vengono inviati dinamicamente. Un avviso o un errore può dirti che hai un potenziale problema, ma la mancanza di uno non garantisce che non avrai errori di runtime.


Modifica: un altro buon modo per rilevare metodi (potenzialmente) inutilizzati è esaminare la copertura del codice dalle esecuzioni effettive. Questo di solito viene fatto in tandem con i test automatici delle unità, ma non è necessario.

Questo post del blog è un'introduzione decente al test di unità e alla copertura del codice utilizzando Xcode. La sezione su gcov(che funziona solo con il codice generato da GCC, tra l'altro) spiega come ottenere Xcode per creare codice strumentato in grado di registrare la frequenza con cui è stato eseguito. Se prendi una build strumentata della tua app per un giro nel simulatore, quindi esegui gcov su di essa, puoi vedere quale codice è stato eseguito utilizzando uno strumento come CoverStory (una GUI abbastanza semplicistica) o lcov(script Perl per creare report HTML) .

Uso gcove lcovper CHDataStructures.framework e genera automaticamente rapporti di copertura dopo ogni commit SVN. Ancora una volta, ricorda che non è saggio trattare la copertura eseguita come una misura definitiva di ciò che il codice è "morto", ma può certamente aiutare a identificare i metodi che puoi investigare ulteriormente.

Infine, dal momento che stai cercando di rimuovere il codice morto, penso che troverai interessante anche questa domanda SO:


4
Non sono sicuro di quale sia il tuo punto ... L'analizzatore statico può trovare molti problemi, ma se invii un messaggio a una variabile digitata come id, o crei un selettore da chiamare in fase di esecuzione, l'analizzatore statico non può garantire che il codice è veramente inutilizzato. Se il codice ancora necessario viene rimosso, è lì che si ottengono errori di runtime. Mi sto perdendo qualcosa?
Quinn Taylor,

1
Inoltre, i selettori creati in base a stringhe in fase di esecuzione sono abbastanza comuni.
dreamlax

1
Naturalmente, ci sono casi in cui il tuo codice dinamico potrebbe essere servito meglio con un cast di tipo più forte (cioè restituire qualcosa invece di un id). La digitazione runtime è un punto di forza della programmazione Cocoa / Objective-C, ma a volte la manutenzione e la leggibilità sarebbero meglio servite pensando di più alla digitazione forte.
alesplin

3
Oh, sono decisamente d'accordo. La mia regola pratica è digitare staticamente (come farei in Java) a meno che non abbia davvero bisogno di una digitazione dinamica, cosa rara ma che accade occasionalmente. Tuttavia, solo l'interfacciamento con le classi Cocoa (ad esempio, la specifica di un delegato) può comportare dinamismo e percorsi di esecuzione difficili da rintracciare. Diamine, qualsiasi programma con un ciclo di esecuzione e più thread può essere non banale ...
Quinn Taylor,

40

Appcode ha una funzione di ispezione del codice che trova le importazioni e il codice inutilizzati.


18
Quindi, vuoi dire che dovremmo installare Appcode solo per questa funzione?
mayqiyue

Se ti è utile, sì!
rmp251


5

Recentemente ho scritto uno script per trovare #importdichiarazioni inutilizzate (o duplicate) : https://gist.github.com/Orangenhain/7691314

Lo script prende un file ObjC .m e inizia a commentare ogni #importriga a turno e vedere se il progetto viene ancora compilato. Dovrai modificare BUILD_DIR e BUILD_CMD.

Se stai utilizzando un findcomando per consentire l'esecuzione dello script su più file, assicurati di utilizzare BUILD_CMD che utilizzi effettivamente tutti quei file (o vedrai un file con molte istruzioni di importazione inutilizzate).

L'ho scritto senza sapere che AppCode ha una caratteristica simile, tuttavia quando ho testato AppCode non era così completo come questo script (ma molto più veloce [per un intero progetto]).


Funziona solo per i duplicati, le importazioni inutilizzate non vengono rimosse.
Rahul



1

Recentemente, ho cambiato un grande progetto da Carbon a Cocoa. Alla fine di questo, c'erano parecchi file orfani che non erano più utilizzati. Ho scritto uno script per trovarli che essenzialmente facevano questo:

Assicurati che il sorgente sia tutto archiviato in subversion (cioè pulito) Assicurati che attualmente compili senza errori (cioè, xcodebuild restituisce lo stato 0) Quindi, per ogni file sorgente nella directory, vuoto (cioè rimuovi il contenuto, tronca la lunghezza) il source e il file di intestazione, prova una build, se fallisce, ripristina i file, altrimenti lasciali vuoti.

Dopo aver eseguito questo, ripristinare e quindi eliminare tutti i file svuotati, compilare e quindi rimuovere tutti gli errori #imports.

Dovrei anche aggiungere che è necessario evitare file a cui si fa riferimento da file .xib o .sdef e potrebbero esserci altri casi di collegamento dinamico, ma può comunque darti un buon vantaggio su ciò che può essere eliminato.

La stessa tecnica può essere utilizzata per vedere quali #import possono essere rimosse: invece di troncare il file, rimuovere a turno ogni #import nel file e vedere se la compilazione fallisce.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.