Как обнаружить неиспользуемые методы и #import в Objective-C

100

После долгой работы над приложением для iPhone я понял, что мой код довольно грязный, содержащий несколько #import и методов, которые вообще не вызываются или не используются.

Я хотел бы знать, есть ли какая-нибудь директива компилятора или способ обнаружить эти бесполезные строки кода. Есть ли у Xcode какой-нибудь инструмент для обнаружения этого?

Гекторет
источник

Ответы:

66

Xcode позволяет вам (отменить) проверку настроек на наличие определенных предупреждений компилятора, которые могут предупредить вас о некоторых типах неиспользуемого кода. (Выберите проект в списке источников и выберите «Файл»> «Получить информацию», затем выберите вкладку «Сборка»). Вот несколько (которые отображаются для меня в Clang и GCC 4.2), которые могут быть интересны:

  • Неиспользуемые функции
  • Неиспользуемые параметры
  • Неиспользованные значения

Я не вижу никаких вариантов для обнаружения неиспользуемого импорта, но это немного проще - низкотехнологичный подход заключается в том, чтобы просто закомментировать операторы импорта, пока вы не получите ошибку / предупреждение компиляции.

Неиспользуемые методы Objective-C гораздо сложнее обнаружить, чем неиспользуемые функции C, потому что сообщения отправляются динамически. Предупреждение или ошибка могут сказать вам, что у вас есть потенциальная проблема, но ее отсутствие не гарантирует, что у вас не будет ошибок времени выполнения.


Изменить: еще один хороший способ обнаружить (потенциально) неиспользуемые методы - изучить покрытие кода от фактических выполнений. Обычно это делается в тандеме с автоматическим модульным тестированием, но это не обязательно.

Это сообщение в блоге - достойное введение в модульное тестирование и покрытие кода с помощью Xcode. В разделе gcov(который, кстати, работает только с кодом, сгенерированным GCC) объясняется, как заставить Xcode создавать инструментальный код, который может записывать, как часто он выполнялся. Если вы возьмете инструментальную сборку своего приложения для вращения в симуляторе, а затем запустите на нем gcov, вы сможете увидеть, какой код был выполнен с помощью такого инструмента, как CoverStory (довольно упрощенный графический интерфейс) или lcov(сценарии Perl для создания отчетов в формате HTML). .

Я использую gcovи lcovдля CHDataStructures.framework и автоматически генерирую отчеты о покрытии после каждой фиксации SVN. Опять же, помните, что неразумно рассматривать выполненное покрытие как окончательную меру того, какой код «мертв», но это, безусловно, может помочь определить методы, которые вы можете исследовать дальше.

Наконец, поскольку вы пытаетесь удалить мертвый код, я думаю, вам также будет интересен этот вопрос SO:

Куинн Тейлор
источник
4
Я не уверен, о чем вы говорите ... Статический анализатор может найти много проблем, но если вы отправляете сообщение переменной, набранной как id, или создаете селектор для вызова во время выполнения, статический анализатор не может гарантировать что код действительно не используется. Если код, который все еще нужен, будет удален, вы получите ошибки времени выполнения. Я что-то упускаю?
Куинн Тейлор,
1
Кроме того, довольно часто встречаются селекторы, которые создаются на основе строк во время выполнения.
dreamlax
1
Конечно, бывают случаи, когда ваш динамический код может быть лучше обслуживается более сильным приведением типов (т.е. возвращать что-то вместо идентификатора). Типизация во время выполнения - сильная сторона программирования на Какао / Objective-C, но иногда для обслуживания и удобочитаемости лучше подумать о строгой типизации.
alesplin
3
О, я определенно согласен. Мое практическое правило - печатать статически (как в Java), если мне действительно не нужна динамическая типизация, что бывает редко, но иногда случается. Однако простое взаимодействие с классами Какао (например, указание делегата) может привести к трудно отслеживаемым динамизмам и путям выполнения. Черт возьми, любая программа с циклом выполнения и несколькими потоками может быть нетривиальной ...
Куинн Тейлор,
40

В Appcode есть функция проверки кода, которая находит неиспользуемый импорт и код.

Патрик-Фитцджеральд
источник
18
Итак, вы имеете в виду, что мы должны установить Appcode только для этой функции?
mayqiyue
Если вам это пригодится, да!
rmp251 07
5

Недавно я написал сценарий для поиска неиспользуемых (или повторяющихся) #importоператоров: https://gist.github.com/Orangenhain/7691314

Сценарий берет файл ObjC .m и начинает по #importочереди комментировать каждую строку и проверять, компилируется ли проект. Вам нужно будет изменить BUILD_DIR и BUILD_CMD.

Если вы используете findкоманду, позволяющую скрипту запускать несколько файлов, убедитесь, что вы используете BUILD_CMD, который фактически использует все эти файлы (или вы увидите файл с множеством неиспользуемых операторов импорта).

Я написал это, не зная, что AppCode имеет аналогичную функцию, однако, когда я тестировал AppCode, он был не таким тщательным, как этот скрипт (но намного быстрее [для всего проекта]).

Орангенхайн
источник
Работает только для дубликатов, неиспользуемый импорт не удаляется.
Рахул
2

Вы можете использовать Xcode Analyzer, чтобы найти эту и другие проблемы.

http://help.apple.com/xcode/mac/8.0/#/devb7babe820

Также вы можете перейти к проекту и целевой сборке и добавить настройки предупреждений об изменении в настройках сборки. См. Это руководство:

http://oleb.net/blog/2013/04/compiler-warnings-for-objective-c-developers/

сиви
источник
1

Недавно я сменил большой проект с Carbon на Cocoa. В конце концов, было довольно много потерянных файлов, которые больше не использовались. Я написал сценарий, чтобы найти их, которые, по сути, сделали это:

Убедитесь, что исходный код зарегистрирован на подрывную версию (т.е. очищен). Убедитесь, что он в настоящее время строится без ошибок (т.е. xcodebuild возвращает статус 0). Затем для каждого исходного файла в каталоге пустой (т.е. удалить содержимое, обрезать длину) source и заголовочный файл, попробуйте сборку, если она не удалась, верните файлы, в противном случае оставьте их пустыми.

После запуска вернитесь, а затем удалите все очищенные файлы, скомпилируйте и затем удалите все ошибочные #imports.

Я также должен добавить, что вам нужно избегать файлов, на которые есть ссылки из файлов .xib или .sdef, и могут быть другие случаи динамического связывания, но это все равно может дать вам хорошее представление о том, что можно удалить.

Тот же метод можно использовать, чтобы увидеть, какие #imports можно удалить - вместо усечения файла удалите каждый #import в файле по очереди и посмотрите, не завершится ли сборка.

Питер Н. Льюис
источник