Saya diberitahu ini beberapa kali di situs ini, tetapi saya ingin memastikan ini benar-benar terjadi.
Saya berharap dapat menaburkan panggilan fungsi NSLog di seluruh kode saya, dan bahwa Xcode / gcc akan secara otomatis menghapus panggilan-panggilan itu ketika membangun rilis / distribusi saya dibangun.
Haruskah saya menghindari menggunakan ini? Jika demikian, alternatif apa yang paling umum di antara programmer Objective-C berpengalaman?
iphone
objective-c
nslog
jpm
sumber
sumber
Jawaban:
Makro preprocessor memang bagus untuk debugging. Tidak ada yang salah dengan NSLog (), tetapi mudah untuk mendefinisikan fungsi logging Anda sendiri dengan fungsionalitas yang lebih baik. Ini yang saya gunakan, termasuk nama file dan nomor baris untuk memudahkan melacak pernyataan log.
Saya merasa lebih mudah untuk menempatkan seluruh pernyataan ini di header awalan daripada file sendiri. Anda bisa, jika mau, membangun sistem logging yang lebih rumit dengan membuat DebugLog berinteraksi dengan objek Objective-C yang normal. Misalnya, Anda bisa memiliki kelas logging yang menulis ke file log sendiri (atau database), dan menyertakan argumen 'prioritas' yang dapat Anda atur saat runtime, sehingga pesan debug tidak ditampilkan dalam versi rilis Anda, tetapi pesan kesalahannya adalah ( jika Anda melakukan ini, Anda bisa membuat DebugLog (), WarningLog (), dan sebagainya).
Oh, dan perlu diingat
#define DEBUG_MODE
dapat digunakan kembali di berbagai tempat dalam aplikasi Anda. Misalnya, dalam aplikasi saya, saya menggunakannya untuk menonaktifkan pemeriksaan kunci lisensi dan hanya mengizinkan aplikasi untuk menjalankannya sebelum tanggal tertentu. Ini memungkinkan saya mendistribusikan salinan beta yang berfungsi penuh dan terbatas waktu dengan sedikit usaha di pihak saya.sumber
Letakkan 3 baris ini di akhir file -prefix.pch:
Anda tidak perlu mendefinisikan apa pun ke dalam proyek Anda, karena
DEBUG
ditentukan dalam pengaturan build Anda secara default ketika Anda membuat proyek Anda.sumber
Panggilan NSLog dapat dibiarkan dalam kode produksi, tetapi hanya boleh ada untuk kasus yang benar-benar luar biasa, atau informasi yang diinginkan yang akan dicatat ke log sistem.
Aplikasi yang mengotori log sistem menjengkelkan, dan dianggap tidak profesional.
sumber
Saya tidak dapat mengomentari jawaban Marc Charbonneau , jadi saya akan memposting ini sebagai jawaban.
Lebih lanjut untuk menambahkan makro ke header yang sudah dikompilasi sebelumnya, Anda dapat menggunakan konfigurasi build Target untuk mengontrol mendefinisikan (atau kurang mendefinisikan) the
DEBUG_MODE
.Jika Anda memilih konfigurasi aktif " Debug ",
DEBUG_MODE
akan ditentukan, dan makro memperluas keNSLog
definisi penuh .Memilih konfigurasi aktif " Release " tidak akan menentukan
DEBUG_MODE
danNSLog
ging Anda dihilangkan dari rilis build.Langkah:
GCC_PREPROCESSOR_DEFINITIONS
)DEBUG_MODE=1
DEBUG_MODE
tidak diaturGCC_PREPROCESSOR_DEFINITIONS
jika Anda menghilangkan karakter '=' dalam definisi, Anda akan mendapatkan kesalahan dari preprocessor
Juga, tempel komentar ini (ditunjukkan di bawah) di atas definisi makro untuk mengingatkan Anda dari mana
DEBUG_MACRO
definisi berasal;)sumber
DEBUG_MODE
danDEBUG_MACRO
tidak konvensional. Saya hanya menemukan satu referensiDEBUG_MACRO
di situs apple ( opensource.apple.com/source/gm4/gm4-15/src/m4.h?txt ). Mungkin lebih standarDEBUG
danNDEBUG
akan menjadi pilihan yang lebih baik?NDEBUG
ditentukan oleh Posix; sementaraDEBUG
digunakan oleh konvensi.EDIT: The Metode diposting oleh Marc Charbonneau , dan dibawa ke perhatian saya dengan sho , jauh lebih baik daripada satu ini.
Saya telah menghapus bagian dari jawaban saya yang disarankan menggunakan fungsi kosong untuk menonaktifkan logging ketika mode debug dinonaktifkan. Bagian yang berhubungan dengan pengaturan makro preprosesor otomatis masih relevan, jadi tetap. Saya juga telah mengedit nama makro preprosesor sehingga lebih cocok dengan jawaban Marc Charbonneau.
Untuk mencapai perilaku otomatis (dan yang diharapkan) dalam Xcode:
Di pengaturan proyek, buka tab "Bangun", dan pilih konfigurasi "Debug". Temukan bagian "Preprocessor Macros", dan tambahkan makro bernama
DEBUG_MODE
....
EDIT: Lihat jawaban Marc Charbonneau untuk cara yang tepat untuk mengaktifkan dan menonaktifkan logging dengan
DEBUG_MODE
makro.sumber
Saya setuju dengan Matthew. Tidak ada yang salah dengan NSLog dalam kode produksi. Bahkan, ini bisa bermanfaat bagi pengguna. Yang mengatakan, jika satu-satunya alasan Anda menggunakan NSLog adalah untuk membantu debug, maka, ya, itu harus dihapus sebelum Anda rilis.
Selain itu, karena Anda telah menandai ini sebagai pertanyaan iPhone, NSLog membutuhkan sumber daya, yang merupakan sesuatu yang berharga sedikit dari iPhone. Jika Anda NSLogging apa pun di iPhone, itu menghilangkan waktu prosesor dari aplikasi Anda. Gunakan dengan bijak.
sumber
Kebenaran sederhana adalah bahwa NSLog sangat lambat.
Tapi kenapa? Untuk menjawab pertanyaan itu, mari cari tahu apa yang dilakukan NSLog, lalu bagaimana cara melakukannya.
Apa yang dilakukan NSLog tepatnya?
NSLog melakukan 2 hal:
Itu menulis pesan log ke fasilitas Apple System Logging (asl). Ini memungkinkan pesan log muncul di Console.app. Itu juga memeriksa untuk melihat apakah aliran stderr aplikasi pergi ke terminal (seperti ketika aplikasi dijalankan melalui Xcode). Jika demikian, ia menulis pesan log ke stderr (sehingga muncul di konsol Xcode).
Menulis ke STDERR tidak terdengar sulit. Itu dapat diselesaikan dengan fprintf dan referensi deskriptor file stderr. Tapi bagaimana dengan dpl?
Dokumentasi terbaik yang saya temukan tentang ASL adalah posting blog 10 bagian dari Peter Hosey: tautan
Tanpa terlalu banyak detail, sorotan (karena menyangkut kinerja) adalah ini:
Untuk mengirim pesan log ke fasilitas ASL, Anda pada dasarnya membuka koneksi klien ke daemon ASL dan mengirim pesan. TETAPI - setiap utas harus menggunakan koneksi klien yang terpisah. Jadi, agar aman thread, setiap kali NSLog dipanggil membuka koneksi klien asl baru, mengirim pesan, dan kemudian menutup koneksi.
Sumber daya dapat ditemukan di sini & di sini .
sumber
Seperti disebutkan dalam jawaban lain, Anda dapat menggunakan #define untuk mengubah apakah NSLog digunakan atau tidak pada waktu kompilasi.
Namun cara yang lebih fleksibel adalah dengan menggunakan perpustakaan logging seperti Cocoa Lumberjack yang memungkinkan Anda untuk mengubah apakah ada sesuatu yang dicatat saat runtime juga.
Dalam kode Anda, ganti NSLog dengan DDLogVerbose atau DDLogError dll, tambahkan #import untuk definisi makro dll dan setup logger, sering kali dalam metode applicationDidFinishLaunching.
Untuk memiliki efek yang sama dengan NSLog, kode konfigurasinya adalah
sumber
Dari sudut pandang keamanan, itu tergantung pada apa yang sedang dicatat. Jika
NSLog
(atau penebang lain) sedang menulis informasi sensitif, maka Anda harus menghapus logger dalam kode produksi.Dari sudut pandang audit, auditor tidak ingin melihat setiap penggunaan
NSLog
untuk memastikan tidak mencatat informasi sensitif. Dia hanya akan memberitahu Anda untuk menghapus logger.Saya bekerja dengan kedua kelompok. Kami mengaudit kode, menulis panduan pengkodean, dll. Panduan kami mengharuskan penebangan dinonaktifkan dalam kode produksi. Jadi tim internal tahu untuk tidak mencobanya;)
Kami juga akan menolak aplikasi eksternal yang mencatat produksi karena kami tidak ingin menerima risiko terkait dengan bocornya informasi sensitif. Kami tidak peduli apa yang dikatakan pengembang kepada kami. Sama sekali tidak layak waktu kita untuk menyelidiki.
Dan ingat, kami mendefinisikan 'sensitif', dan bukan pengembang;)
Saya juga melihat aplikasi yang melakukan banyak logging sebagai aplikasi yang siap meledak. Ada alasan mengapa begitu banyak logging dilakukan / dibutuhkan, dan biasanya tidak stabil. Tepat di sana dengan utas pengawas yang memulai kembali layanan yang digantung.
Jika Anda belum pernah melalui tinjauan Arsitektur Keamanan (SecArch), ini adalah beberapa hal yang kami lihat.
sumber
Anda seharusnya tidak perlu bertele-tele dengan printf atau NSLog dalam kode rilis. Cobalah hanya melakukan printf atau NSLog jika aplikasi memiliki sesuatu yang buruk terjadi, yaitu kesalahan yang tidak dapat dipulihkan.
sumber
Perlu diingat bahwa NSLogs dapat memperlambat UI / utas utama. Yang terbaik adalah menghapusnya dari rilis build kecuali benar-benar diperlukan.
sumber
Saya akan sangat menyarankan menggunakan TestFlight untuk logging (gratis). Metode mereka akan menimpa NSLog (menggunakan makro) dan memungkinkan Anda untuk mengaktifkan / menonaktifkan logging ke server mereka, log Sistem Apple dan log STDERR, untuk semua panggilan Anda yang ada ke NSLog. Yang menyenangkan tentang ini adalah Anda masih dapat meninjau pesan log Anda untuk aplikasi yang digunakan untuk penguji dan aplikasi yang digunakan di App Store, tanpa log yang muncul di log sistem pengguna. Terbaik dari kedua dunia.
sumber