Cara mendeteksi metode yang tidak digunakan dan #import di Objective-C

100

Setelah bekerja lama di aplikasi iPhone, saya menyadari bahwa kode saya cukup kotor, berisi beberapa #import dan metode yang tidak dipanggil atau tidak berguna sama sekali.

Saya ingin tahu apakah ada arahan kompilator atau cara untuk mendeteksi baris kode yang tidak berguna itu. Apakah Xcode memiliki alat untuk mendeteksi ini?

Hectoret
sumber

Jawaban:

66

Xcode memungkinkan Anda untuk (tidak) memeriksa pengaturan untuk peringatan compiler tertentu yang dapat memperingatkan Anda tentang beberapa jenis kode yang tidak digunakan. (Pilih proyek di daftar sumber dan File> Dapatkan Info, lalu pilih tab Bangun.) Berikut beberapa (yang muncul untuk Clang dan GCC 4.2 untuk saya) yang mungkin menarik:

  • Fungsi yang Tidak Digunakan
  • Parameter yang Tidak Digunakan
  • Nilai yang Tidak Digunakan

Saya tidak melihat opsi apa pun untuk mendeteksi impor yang tidak digunakan, tetapi itu sedikit lebih sederhana - pendekatan berteknologi rendah hanya dengan mengomentari pernyataan impor sampai Anda mendapatkan kesalahan / peringatan kompilasi.

Metode Objective-C yang tidak digunakan jauh lebih sulit untuk dideteksi daripada fungsi C yang tidak digunakan karena pesan dikirim secara dinamis. Peringatan atau kesalahan dapat memberi tahu Anda bahwa Anda memiliki potensi masalah, tetapi kurangnya masalah tidak menjamin Anda tidak akan mengalami kesalahan waktu proses.


Edit: Cara lain yang baik untuk mendeteksi (berpotensi) metode yang tidak digunakan adalah dengan memeriksa cakupan kode dari eksekusi sebenarnya. Ini biasanya dilakukan bersama-sama dengan pengujian unit otomatis, tetapi tidak harus begitu.

Posting blog ini adalah pengantar yang layak untuk pengujian unit dan cakupan kode menggunakan Xcode. Bagian gcov(yang hanya berfungsi dengan kode yang dihasilkan oleh GCC) menjelaskan cara mendapatkan Xcode untuk membuat kode berinstrumen yang dapat mencatat seberapa sering kode tersebut dijalankan. Jika Anda mengambil build terinstrumentasi dari aplikasi Anda untuk berputar di simulator, lalu menjalankan gcov di dalamnya, Anda dapat melihat kode apa yang dijalankan dengan menggunakan alat seperti CoverStory (GUI yang cukup sederhana) atau lcov(skrip Perl untuk membuat laporan HTML) .

Saya menggunakan gcovdan lcovuntuk CHDataStructures.framework dan membuat laporan cakupan secara otomatis setelah setiap SVN komit. Sekali lagi, ingatlah bahwa tidak bijaksana memperlakukan cakupan yang dieksekusi sebagai ukuran pasti dari kode apa yang "mati", tetapi tentu saja hal itu dapat membantu mengidentifikasi metode yang dapat Anda selidiki lebih lanjut.

Terakhir, karena Anda mencoba menghapus kode mati, saya pikir Anda akan menemukan pertanyaan SO ini menarik juga:

Quinn Taylor
sumber
4
Saya tidak yakin apa maksud Anda ... Penganalisis statis dapat menemukan banyak masalah, tetapi jika Anda mengirimkan pesan ke variabel yang diketik sebagai id, atau membuat pemilih untuk dipanggil saat runtime, penganalisis statis tidak dapat menjamin bahwa kode tersebut benar-benar tidak digunakan. Jika kode yang masih diperlukan dihapus, di situlah Anda akan mendapatkan error runtime. Apakah saya melewatkan sesuatu?
Quinn Taylor
1
Selain itu, penyeleksi yang dibuat berdasarkan string pada waktu proses cukup umum.
dreamlax
1
Tentu saja, ada beberapa kasus di mana kode dinamis Anda mungkin lebih baik disajikan dengan menggunakan tipe-cast yang lebih kuat (mis. Mengembalikan sesuatu daripada id). Pengetikan waktu proses adalah poin penting dari pemrograman Cocoa / Objective-C, tetapi terkadang pemeliharaan dan keterbacaan akan lebih baik disajikan dengan memikirkan lebih banyak tentang pengetikan yang kuat.
alesplin
3
Oh, saya sangat setuju. Aturan praktis saya adalah mengetik secara statis (seperti yang saya lakukan di Java) kecuali saya benar-benar membutuhkan pengetikan dinamis, yang jarang terjadi tetapi kadang-kadang terjadi. Namun, hanya berinteraksi dengan kelas Cocoa (misalnya, menentukan delegasi) dapat mengakibatkan dinamisme dan jalur eksekusi yang sulit dilacak. Heck, program apa pun dengan run loop dan banyak utas bisa jadi tidak sepele ...
Quinn Taylor
40

Appcode memiliki fitur pemeriksaan kode yang menemukan impor dan kode yang tidak digunakan.

patrick-fitzgerald
sumber
18
Jadi, maksud Anda kita harus menginstal Appcode hanya untuk fitur ini?
mayqiyue
Jika itu berguna bagi Anda, ya!
rmp251
5

Saya baru-baru ini menulis skrip untuk menemukan #importpernyataan yang tidak digunakan (atau duplikat) : https://gist.github.com/Orangenhain/7691314

Skrip mengambil file ObjC .m dan mulai memberi komentar masing-masing #import baris secara bergantian dan melihat apakah proyek masih terkompilasi. Anda harus mengubah BUILD_DIR & BUILD_CMD.

Jika Anda menggunakan findperintah untuk membiarkan skrip menjalankan beberapa file, pastikan untuk menggunakan BUILD_CMD yang benar-benar menggunakan semua file tersebut (atau Anda akan melihat file dengan banyak pernyataan impor yang tidak digunakan).

Saya menulis ini tanpa mengetahui AppCode memiliki fitur serupa, namun ketika saya menguji AppCode itu tidak selengkap skrip ini (tetapi jauh lebih cepat [untuk keseluruhan proyek]).

Orangenhain
sumber
Ini hanya berfungsi untuk duplikat, impor yang tidak digunakan tidak dihapus.
Rahul
1

Baru-baru ini, saya mengubah proyek besar dari Karbon menjadi Kakao. Pada akhirnya, ada beberapa file yatim piatu yang tidak lagi digunakan. Saya menulis skrip untuk menemukan mereka yang pada dasarnya melakukan ini:

Pastikan sumber semuanya diperiksa ke subversi (yaitu bersih) Pastikan saat ini dibangun tanpa kesalahan (yaitu, xcodebuild mengembalikan status 0) Kemudian, untuk setiap file sumber dalam direktori, kosongkan (yaitu, hapus isinya, potong panjangnya) source dan file header, coba build, jika gagal, kembalikan file, jika tidak, biarkan kosong.

Setelah menjalankan ini, kembalikan dan kemudian hapus semua file yang dikosongkan, kompilasi dan kemudian hapus semua kesalahan #imports.

Saya juga harus menambahkan, Anda perlu menghindari file yang direferensikan dari file .xib atau .sdef, dan mungkin ada kasus penautan dinamis lainnya, tetapi masih dapat memberi Anda petunjuk yang baik tentang apa yang dapat dihapus.

Teknik yang sama dapat digunakan untuk melihat #import mana yang dapat dihapus - daripada memotong file, hapus setiap #import dalam file secara bergantian dan lihat apakah build gagal.

Peter N Lewis
sumber