Swift: print () vs println () vs NSLog ()

450

Apa perbedaan antara print, NSLogdan printlndan ketika saya harus menggunakan masing-masing?

Sebagai contoh, dengan Python jika saya ingin mencetak kamus, saya baru saja print myDict, tetapi sekarang saya memiliki 2 pilihan lain. Bagaimana dan kapan saya harus menggunakan masing-masing?

Pengguna
sumber
1
kemungkinan rangkap dari Perbedaan antara println dan print di Swift
Connor
2
bagaimana dengan NSLog dan mencetak NSDictionary tidak memberi saya sesuatu yang berguna?
Pengguna
Dari iOS 10.0 maju, disarankan menggunakan satu os_log. Silakan lihat jawaban saya di bawah ini .
HuaTham
Selain melihat dokumentasi Swift pada os_log: coba lihat dokumentasi lengkap halaman tujuan-C. Jauh lebih lengkap .
Sayang

Jawaban:

758

Beberapa perbedaan:

  1. printvs println:

    The printfungsi cetak pesan di konsol Xcode saat debugging aplikasi.

    Ini printlnadalah variasi dari ini yang telah dihapus di Swift 2 dan tidak digunakan lagi. Jika Anda melihat kode lama yang digunakan println, kini Anda dapat menggantinya dengan aman print.

    Kembali di Swift 1.x, printtidak menambahkan karakter baris baru di akhir string yang dicetak, sedangkan printlnitu. Tetapi saat ini, printselalu tambahkan karakter baris baru di akhir string, dan jika Anda tidak ingin melakukannya, berikan terminatorparameter "".

  2. NSLog:

    • NSLog lebih lambat;

    • NSLogmenambahkan cap waktu dan pengidentifikasi ke output, sedangkan printtidak akan;

    • NSLogpernyataan muncul di konsol perangkat dan konsol debugger sedangkan printhanya muncul di konsol debugger.

    • NSLogmenggunakan printfstring format -style, mis

      NSLog("%0.4f", CGFloat.pi)

      yang akan menghasilkan:

      2017-06-09 11: 57: 55.642328-0700 MyApp [28937: 1751492] 3.1416

  3. IOS 10 / macOS 10.12 yang efektif, ada alternatif ketiga os_log, bagian dari sistem "pencatatan terpadu" (lihat video WWDC 2016 Pencatatan Terpadu dan Pelacakan Aktivitas ).

    • Anda harus mengimpor os.logsebelum menggunakan os_logfungsi:

      import os.log
    • Seperti NSLog, os_logakan menampilkan pesan ke konsol debugging Xcode dan konsol perangkat juga

    • Anda sekarang dapat mengontrol bidang "subsistem" dan "kategori" yang tersedia di aplikasi Konsol. Sebagai contoh:

      let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
      os_log("url = %@", log: log, url.absoluteString)
      

      Saat Anda mengamati aplikasi melalui aplikasi Konsol eksternal, Anda tidak hanya dapat menambahkan kolom ini ke tampilan utama, tetapi Anda dapat memfilter berdasarkan ini. Ini sangat berguna ketika ingin membedakan pesan debug Anda dari (a) yang dihasilkan oleh subsistem lain atas nama aplikasi Anda; atau (b) pesan dari kategori atau tipe lain.

    • Anda dapat menentukan jenis penebangan pesan, baik .info, .debug, .error, .fault(atau .default):

      os_log("web service did not respond", type: .error)

      Jadi, jika menggunakan aplikasi Konsol eksternal, Anda dapat memilih untuk hanya melihat pesan dari kategori tertentu (mis. Hanya menampilkan pesan debug jika Anda memilih "Sertakan Pesan Debug" pada menu "Aksi" Konsol). Pengaturan ini juga menentukan banyak detail masalah yang halus tentang apakah sesuatu masuk ke disk atau tidak. Lihat video WWDC untuk lebih jelasnya.

    • Anda tidak dapat menggunakan interpolasi string saat menggunakan os_log. Misalnya, Anda tidak dapat melakukan:

      os_log("foo \(url.absoluteString)")

      Anda harus melakukan:

      os_log("url = %@", url.absoluteString)
    • Salah satu alasan untuk pembatasan di atas adalah untuk mendukung privasi data. Tipe data primitif (mis. Angka) bersifat publik secara default dan objek (mis. String) bersifat pribadi secara default. Pada contoh sebelumnya di mana Anda login URL, jika aplikasi itu dipanggil dari perangkat itu sendiri dan Anda menonton dari aplikasi Konsol Mac Anda, Anda akan melihat:

      url = <private>

      Jika Anda ingin melihatnya dari perangkat eksternal, Anda harus melakukannya:

      os_log("url = %{public}@", url.absoluteString)
    • Catatan, NSLogsekarang menggunakan sistem notifikasi terpadu di belakang layar, tetapi dengan peringatan berikut:

      • Anda tidak dapat mengontrol subsistem atau kategori atau tipe log;

      • Itu tidak mendukung pengaturan privasi.

Intinya, printcukup untuk tugas-tugas sederhana, tetapi NSLogberguna karena termasuk informasi timestamp untuk Anda.

Kekuatan os_loglega jelas ketika men-debug aplikasi iOS yang harus diuji di luar Xcode. Misalnya, saat menguji latar belakang proses aplikasi iOS seperti pengambilan latar belakang, terhubung ke debugger Xcode mengubah siklus hidup aplikasi . Jadi, Anda sering ingin menguji pada perangkat fisik, menjalankan aplikasi dari perangkat itu sendiri, bukan memulai aplikasi dari debugger Xcode. Pencatatan terpadu memungkinkan Anda masih menonton os_logpernyataan perangkat iOS Anda dari aplikasi Konsol macOS.

rampok
sumber
37
Ringkasan yang bagus! Untuk menambahkan beberapa lagi: Anda dapat meneruskan NSString ke println, tetapi tidak NSLog; Anda dapat menambahkan args untuk NSLog, tetapi tidak println; Interpolasi string gaya Swift terkadang macet untuk NSLog, tetapi tidak println.
Bao Lei
2
catatan menarik tentang optimisasi kompiler Swift dan penggunaan print () medium.com/ios-os-x-development/…
Carl
@ Rob jika saya menggunakan cetak maka apakah itu muncul di konsol debugger atau tidak? Atau haruskah kita menggunakan debugPrint?
1
Jika Anda menggunakan print, itu muncul di area debug Xcode, sama seperti debugPrint. Satu-satunya perbedaan adalah bahwa printakhirnya memanggil descriptionmetode objek, dan debugPrintpanggilan debugDescription, yang mungkin lebih bertele-tele daripada description.
Rob
@ Sayang, utas komentar ini ditandai terlalu panjang, jadi saya hanya ingin mengingatkan Anda bahwa komentar bukan untuk diskusi panjang atau sesi debugging. Jika Anda memiliki sesuatu yang dapat ditanyakan sebagai pertanyaan yang cocok untuk format Stack Overflow, silakan tanyakan sebagai pertanyaan agar semua orang mendapat manfaat dari jawabannya. Jika tidak berfungsi sebagai pertanyaan, maka Anda perlu mengajak diskusi untuk mengobrol. Cadangan komentar hanya untuk meminta klarifikasi atau melakukan pengamatan cepat.
Cody Gray
80

Jika Anda menggunakan Swift 2 , sekarang Anda hanya dapat menggunakan print () untuk menulis sesuatu ke output.

Apple telah menggabungkan fungsi println () dan print () menjadi satu.

Diperbarui ke iOS 9

Secara default, fungsi mengakhiri garis yang dicetak dengan menambahkan garis putus.

print("Hello Swift")

Terminator

Untuk mencetak nilai tanpa putus garis setelahnya, berikan string kosong sebagai terminator

print("Hello Swift", terminator: "")

Pemisah

Anda sekarang dapat menggunakan pemisah untuk menggabungkan beberapa item

print("Hello", "Swift", 2, separator:" ")

Kedua

Atau Anda bisa menggabungkan menggunakan cara ini

print("Hello", "Swift", 2, separator:" ", terminator:".")
Jorge Casariego
sumber
5
appendNewlinememiliki nilai defaulttrue
Adam
1
Di iOS (9.0) Anda perlu menggunakan terminator : "", misalnyaprint("...", terminator: "")
Khotu Nam
Pernyataan dalam kalimat pertama Anda salah. NSLog () masih berfungsi, bahkan di Swift 2.x terbaru
Sebastian
62

Selain itu, Swift 2 memiliki debugPrint()(dan CustomDebugStringConvertibleprotokol)!

Jangan lupa debugPrint()yang berfungsi seperti apa print()tetapi paling cocok untuk debugging .

Contoh:

  • String
    • print("Hello World!") menjadi Hello World
    • debugPrint("Hello World!")menjadi "Hello World"(Kutipan!)
  • Kisaran
    • print(1..<6) menjadi 1..<6
    • debugPrint(1..<6) menjadi Range(1..<6)

Setiap kelas dapat menyesuaikan representasi string debug mereka melalui CustomDebugStringConvertibleprotokol.

Valentin Shergin
sumber
2
DebugPrintableprotokol telah diubah namanya menjadi CustomDebugStringConvertibleprotokol .
Franklin Yu
Terima kasih, Franklin!
Valentin Shergin
Jadi Swift descriptionadalah untuk debugDescriptionsebagai Python stradalah untuk repr?
BallpointBen
Ya saya pikir begitu.
Valentin Shergin
39

Untuk menambah jawaban Rob, sejak iOS 10.0, Apple telah memperkenalkan sistem "Unified Logging" yang sama sekali baru yang menggantikan sistem logging yang ada (termasuk ASL dan Syslog, NSLog), dan juga melampaui pendekatan logging yang ada dalam kinerja, berkat teknik baru termasuk kompresi data log dan pengumpulan data yang ditangguhkan.

Dari Apple :

Sistem pencatatan terpadu menyediakan API tunggal, efisien, berkinerja untuk menangkap pengiriman pesan di semua tingkatan sistem. Sistem terpadu ini memusatkan penyimpanan data log dalam memori dan dalam penyimpanan data pada disk.

Apple sangat menyarankan os_loguntuk maju untuk mencatat semua jenis pesan, termasuk info, debug, pesan kesalahan karena kinerjanya yang jauh lebih baik dibandingkan dengan sistem pencatatan sebelumnya, dan pengumpulan datanya yang terpusat memungkinkan pencatatan log dan aktivitas yang mudah bagi pengembang. Faktanya, sistem baru ini kemungkinan sangat rendah jejaknya sehingga tidak akan menyebabkan "efek pengamat" ketika bug Anda menghilang jika Anda memasukkan perintah logging, mengganggu waktu terjadinya bug.

Kinerja Penelusuran Aktivitas, sekarang menjadi bagian dari sistem Penebangan Bersatu yang baru

Anda dapat mempelajari lebih lanjut tentang ini di sini .

Singkatnya: gunakan print()untuk debugging pribadi Anda untuk kenyamanan (tetapi pesan tidak akan dicatat ketika digunakan pada perangkat pengguna). Kemudian, gunakan Pencatatan Bersatu ( os_log) sebanyak mungkin untuk yang lainnya.

HuaTham
sumber
5

Ada metode lain yang disebut dump()yang juga dapat digunakan untuk login:

func dump<T>(T, name: String?, indent: Int, maxDepth: Int, maxItems: Int)

Membuang konten objek menggunakan cerminnya ke output standar.

Dari Fungsi Perpustakaan Standar Swift

JAL
sumber