So erkennen Sie nicht verwendete Methoden und #import in Objective-C

99

Nachdem ich lange an einer iPhone-App gearbeitet hatte, stellte ich fest, dass mein Code ziemlich schmutzig ist und mehrere #import und Methoden enthält, die überhaupt nicht aufgerufen oder nützlich sind.

Ich würde gerne wissen, ob es eine Compiler-Direktive oder eine Möglichkeit gibt, diese nutzlosen Codezeilen zu erkennen. Hat Xcode ein Tool, um dies zu erkennen?

Hectoret
quelle

Antworten:

66

Mit Xcode können Sie die Einstellungen für bestimmte Compiler-Warnungen (deaktivieren), die Sie vor bestimmten Arten von nicht verwendetem Code warnen können. (Wählen Sie das Projekt in der Quellliste und Datei> Informationen abrufen und dann die Registerkarte Erstellen aus.) Hier sind einige (die für mich für Clang und GCC 4.2 angezeigt werden), die von Interesse sein können:

  • Nicht verwendete Funktionen
  • Nicht verwendete Parameter
  • Nicht verwendete Werte

Ich sehe keine Optionen zum Erkennen nicht verwendeter Importe, aber das ist etwas einfacher - der Low-Tech-Ansatz besteht nur darin, Importanweisungen auskommentieren, bis Sie einen Kompilierungsfehler / eine Warnung erhalten.

Nicht verwendete Objective-C-Methoden sind viel schwieriger zu erkennen als nicht verwendete C-Funktionen, da Nachrichten dynamisch versendet werden. Eine Warnung oder ein Fehler kann Ihnen sagen, dass Sie ein potenzielles Problem haben, aber das Fehlen eines solchen garantiert nicht, dass Sie keine Laufzeitfehler haben.


Bearbeiten: Eine weitere gute Möglichkeit, (möglicherweise) nicht verwendete Methoden zu erkennen, besteht darin, die Codeabdeckung anhand tatsächlicher Ausführungen zu untersuchen. Dies erfolgt normalerweise zusammen mit automatisierten Unit-Tests, muss es aber nicht sein.

Dieser Blog-Beitrag ist eine anständige Einführung in Unit-Tests und Codeabdeckung mit Xcode. In diesem Abschnitt gcov(der übrigens nur mit von GCC generiertem Code funktioniert) wird erläutert, wie Xcode instrumentierten Code erstellt, der aufzeichnet, wie oft er ausgeführt wurde. Wenn Sie einen instrumentierten Build Ihrer App für eine Drehung im Simulator verwenden und dann gcov darauf ausführen, können Sie mithilfe eines Tools wie CoverStory (eine ziemlich vereinfachte Benutzeroberfläche ) oder lcov(Perl-Skripte zum Erstellen von HTML-Berichten) sehen, welcher Code ausgeführt wurde. .

Ich verwende gcovund lcovfür CHDataStructures.framework und generiere automatisch Berichterstattungsberichte nach jedem SVN-Commit. Denken Sie auch hier daran, dass es unklug ist, die ausgeführte Abdeckung als endgültiges Maß dafür zu betrachten, welcher Code "tot" ist, aber es kann sicherlich helfen, Methoden zu identifizieren, die Sie weiter untersuchen können.

Da Sie versuchen, toten Code zu entfernen, finde ich diese SO-Frage auch interessant:

Quinn Taylor
quelle
4
Ich bin mir nicht sicher, worum es Ihnen geht ... Der statische Analysator kann viele Probleme feststellen. Wenn Sie jedoch eine Nachricht an eine Variable senden, die als eingegeben wurde id, oder einen Selektor erstellen, der zur Laufzeit aufgerufen werden kann, kann der statische Analysator keine Garantie übernehmen dass der Code wirklich unbenutzt ist. Wenn noch benötigter Code entfernt wird, treten dort Laufzeitfehler auf. Vermisse ich etwas
Quinn Taylor
1
Darüber hinaus sind Selektoren, die zur Laufzeit basierend auf Zeichenfolgen erstellt werden, weit verbreitet.
Dreamlax
1
Natürlich gibt es Fälle, in denen Ihr dynamischer Code möglicherweise besser bedient wird, indem er stärker typisiert wird (dh etwas anstelle einer ID zurückgibt). Die Laufzeit-Eingabe ist eine Stärke der Cocoa / Objective-C-Programmierung, aber manchmal sind Wartung und Lesbarkeit besser, wenn Sie mehr über eine starke Eingabe nachdenken.
Alesplin
3
Oh, ich stimme definitiv zu. Meine Faustregel lautet, statisch zu tippen (wie in Java), es sei denn, ich benötige wirklich dynamisches Tippen, was selten ist, aber gelegentlich vorkommt. Die bloße Anbindung an Cocoa-Klassen (z. B. Angabe eines Delegaten) kann jedoch zu schwer nachvollziehbarer Dynamik und Ausführungspfaden führen. Heck, jedes Programm mit einer Run-Schleife und mehreren Threads kann nicht trivial sein ...
Quinn Taylor
39

Appcode verfügt über eine Codeüberprüfungsfunktion, die nicht verwendete Importe und Code findet.

patrick-fitzgerald
quelle
17
Sie meinen also, wir sollten Appcode nur für diese Funktion installieren?
Mayqiyue
Wenn es Ihnen nützlich ist, ja!
rmp251
5

Ich habe kürzlich ein Skript geschrieben, um nicht verwendete (oder doppelte) #importAnweisungen zu finden: https://gist.github.com/Orangenhain/7691314

Das Skript nimmt eine ObjC .m-Datei und kommentiert nacheinander jede #importZeile aus, um festzustellen , ob das Projekt noch kompiliert wird. Sie müssen BUILD_DIR & BUILD_CMD ändern.

Wenn Sie einen verwenden findBefehl das Skript laufen über mehrere Dateien zu lassen, stellen Sie sicher , eine BUILD_CMD zu verwenden , die tatsächlich verwendet alle diese Dateien (oder Sie werden eine Datei mit vielen nicht verwendeten Import - Anweisungen sehen).

Ich habe dies geschrieben, ohne zu wissen, dass AppCode eine ähnliche Funktion hat. Als ich AppCode getestet habe, war es jedoch nicht so gründlich wie dieses Skript (aber viel schneller [für ein ganzes Projekt]).

Orangenhain
quelle
Es funktioniert nur für Duplikate, nicht verwendete Importe werden nicht entfernt.
Rahul
1

Kürzlich habe ich ein großes Projekt von Carbon auf Cocoa umgestellt. Am Ende gab es einige verwaiste Dateien, die nicht mehr verwendet wurden. Ich habe ein Skript geschrieben, um sie zu finden, die im Wesentlichen dies taten:

Stellen Sie sicher, dass die Quelle vollständig in Subversion eingecheckt ist (dh bereinigt). Stellen Sie sicher, dass sie derzeit fehlerfrei erstellt wird (dh xcodebuild gibt den Status 0 zurück). Leeren Sie dann für jede Quelldatei im Verzeichnis (dh entfernen Sie den Inhalt, kürzen Sie die Länge) die Quell- und Header-Datei, versuchen Sie einen Build. Wenn dies fehlschlägt, setzen Sie die Dateien zurück, andernfalls lassen Sie sie leer.

Nachdem Sie dies ausgeführt haben, setzen Sie alle geleerten Dateien zurück und löschen Sie sie. Kompilieren Sie alle fehlerhaften # Importe und entfernen Sie sie.

Ich sollte auch hinzufügen, dass Sie Dateien vermeiden müssen, auf die aus .xib- oder .sdef-Dateien verwiesen wird, und es kann andere Fälle dynamischer Verknüpfungen geben, aber es kann Ihnen trotzdem einen guten Hinweis darauf geben, was gelöscht werden kann.

Dieselbe Technik kann verwendet werden, um zu sehen, welche # Importe entfernt werden können. Anstatt die Datei abzuschneiden, entfernen Sie nacheinander jeden # Import in der Datei und prüfen Sie, ob der Build fehlschlägt.

Peter N Lewis
quelle