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


450

У чому різниця між print, NSLogі printlnколи я повинен використовувати кожен?

Наприклад, у Python, якби я хотів надрукувати словник, я би просто так print myDict, але зараз у мене є ще 2 варіанти. Як і коли я повинен використовувати кожен?


1
можливий дублікат Різниці між println та print у Swift
Connor

2
що з NSLog та друком NSDictionary не дає мені нічого корисного?
Користувач

З iOS 10.0 вперед рекомендується використовувати один os_log. Будь ласка, дивіться мою відповідь нижче .
HuaTham

Окрім перегляду документації на Swift на os_log: спробуйте переглянути повну документацію на цілі C-сторінки. Це набагато повніше .
Мед

Відповіді:


758

Кілька відмінностей:

  1. printvs println:

    The print функції виведення повідомлень в консолі Xcode при налагодженні програм.

    Це printlnваріація, яку було видалено в Swift 2 і більше не використовується. Якщо ви бачите старий код, який використовуєте println, тепер можете сміливо замінити йогоprint .

    Ще в Swift 1.x printне було додано символів нового рядка в кінці надрукованого рядка, тоді як println. Але в наш час printзавжди додається символ нового рядка в кінці рядка, і якщо ви цього не бажаєте, введіть terminatorпараметр "".

  2. NSLog:

    • NSLog повільніше;

    • NSLogдодає позначку часу та ідентифікатор до виводу, тоді як printне буде;

    • NSLogоператори відображаються як в консолі пристрою, так і в консолі налагодження, тоді як printз'являються лише в консолі налагодження.

    • NSLogвикористовує printfрядки формату стилю, наприклад

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

      що дасть:

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

  3. Ефективна iOS 10 / macOS 10.12, є третя альтернатива, os_logчастина системи "уніфікованого журналу" (див. Відео Уніфікованого журналу та відстеження активності WWDC 2016 ).

    • Ви повинні імпортувати os.logперед використанням os_logфункції:

      import os.log
    • Мовляв NSLog, os_logбуде виводитися повідомлення і на консоль налагодження Xcode, і на консоль пристрою

    • Тепер ви можете керувати полями "підсистеми" та "категорії", доступними в додатку "Консоль". Наприклад:

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

      Якщо ви спостерігаєте за програмою через зовнішню програму Console, ви можете не тільки додати ці стовпці до основного вікна, але ви можете фільтрувати на основі цих. Це дуже корисно, коли ви хочете розмежувати ваші повідомлення про налагодження від (а) тих, які генеруються іншими підсистемами від імені вашої програми; або (b) повідомлення інших категорій або типів.

    • Ви можете задати різні типи реєстрації повідомлень, або .info, .debug, .error, .fault(або .default):

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

      Отже, якщо ви користуєтеся зовнішньою програмою консолі, ви можете переглядати повідомлення лише певних категорій (наприклад, показувати лише повідомлення про налагодження, якщо у меню консолі "Дія" вибираєте "Включити повідомлення про налагодження"). Ці параметри також диктують багато тонких питань про те, чи реєструються речі на диску чи ні. Дивіться відео WWDC для більш детальної інформації.

    • Ви не можете використовувати інтерполяцію рядків під час використання os_log. Наприклад, ви не можете:

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

      Вам доведеться зробити:

      os_log("url = %@", url.absoluteString)
    • Однією з причин вищезазначеного обмеження є підтримка конфіденційності даних. Примітивні типи даних (наприклад, числа) за замовчуванням є загальнодоступними, а об'єкти (наприклад, рядки) за замовчуванням приватні. У попередньому прикладі, коли ви входили в URL-адресу, якщо додаток викликали з самого пристрою, і ви переглядали з додатка консолі Mac, ви побачите:

      url = <приват>

      Якщо ви хотіли бачити його на зовнішньому пристрої, вам слід зробити:

      os_log("url = %{public}@", url.absoluteString)
    • Зауважте, NSLogзараз використовується уніфікована система сповіщень за кадром, але із наступними застереженнями:

      • Ви не можете керувати підсистемою, категорією чи типом журналу;

      • Він не підтримує налаштування конфіденційності.

Підсумок, printдостатній для простих завдань, алеNSLog корисний, оскільки містить інформацію про часові позначки для вас.

Сила os_logприходить у надзвичайне полегшення під час налагодження програм для iOS, які потрібно перевірити поза Xcode. Наприклад, під час тестування фонових процесів додатків для iOS, таких як отримання фонів, підключення до відладчика Xcode змінює життєвий цикл програми . Отже, вам часто захочеться тестувати на фізичному пристрої, запускаючи додаток із самого пристрою, не запускаючи програму з налагоджувача Xcode. Уніфікований ведення журналу, ми все одно переглядаємо ваші os_logзаяви на пристрої iOS з програми macOS Console.


37
Приємний підсумок! Щоб додати ще декілька: ви можете передати NSString до println, але не NSLog; ви можете додати аргументи для NSLog, але не println; Інтерполяція строкових стилів Swift іноді виходить з ладу для NSLog, але не println.
Бао Лей

2
цікава примітка про оптимізацію компілятора Swift та використання print () medium.com/ios-os-x-development/…
Карл

@Rob, якщо я використовую print, він відображається на консолі налагодження чи ні? Чи слід використовувати debugPrint?

1
Якщо ви використовуєте print, він відображається в області налагодження Xcode, точно так само debugPrint. Єдина відмінність полягає в тому, що printзакінчується descriptionметод виклику об'єкта та debugPrintвиклики debugDescription, які можуть бути більш багатослівними, ніж description.
Роб

@Honey, цей потік коментарів позначено як надмірно довгий, тому я просто хотів нагадати, що коментарі не призначені для розширених сесій обговорення чи налагодження. Якщо у вас є щось, що може бути задано як питання, яке підходить для формату переповнення стека, тоді, будь ласка, задайте це як запитання, щоб кожен отримав користь від його відповідей. Якщо це не спрацює як питання, тоді вам потрібно буде взяти дискусію для спілкування. Зарезервуйте коментарі лише для того, щоб просити роз'яснення або робити швидкі спостереження.
Коді Грей

80

Якщо ви використовуєте Swift 2 , тепер ви можете використовувати тільки print (), щоб написати щось на вихід.

Apple поєднала в одній функції і функції println (), і print () .

Оновлено до iOS 9

За замовчуванням функція припиняє друк рядка, додаючи розрив рядка.

print("Hello Swift")

Термінатор

Щоб надрукувати значення без розриву рядка після нього, передайте порожній рядок як термінатор

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

Роздільник

Тепер ви можете використовувати роздільник для об'єднання декількох елементів

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

І те й інше

Або ви могли поєднувати використання таким чином

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

5
appendNewlineмає значення за замовчуваннямtrue
Адам,

1
У iOS (9.0) вам потрібно користуватися terminator : "", наприкладprint("...", terminator: "")
Khotu Nam

Твердження у першому реченні невірне. NSLog () все ще працює, навіть в останньому Swift 2.x
Себастьян

62

Більше того, у Swift 2 є debugPrint()CustomDebugStringConvertibleпротокол)!

Не забувайте про те, debugPrint()що працює, print()але найбільш підходить для налагодження .

Приклади:

  • Струни
    • print("Hello World!") стає Hello World
    • debugPrint("Hello World!")стає "Hello World"(Котирування!)
  • Діапазони
    • print(1..<6) стає 1..<6
    • debugPrint(1..<6) стає Range(1..<6)

Будь-який клас може налаштувати подання рядка налагодження за допомогою CustomDebugStringConvertibleпротоколу.


2
DebugPrintableпротокол перейменовано на CustomDebugStringConvertibleпротокол .
Франклін Ю

Дякую, Франклін!
Валентин Шергін

Так Свіфт descriptionє , debugDescriptionяк в Python strє repr?
BallpointBen

Так, я так думаю.
Валентин Шергін

39

На додаток до відповіді Роба, починаючи з iOS 10.0, Apple представила абсолютно нову систему "Unified Logging", яка витісняє існуючі системи реєстрації журналів (включаючи ASL та Syslog, NSLog), а також перевершує існуючі підходи до ведення журналу завдяки своїй новій техніці, включаючи стиснення даних журналу та відкладений збір даних.

Від Apple :

Уніфікована система ведення журналів забезпечує єдиний, ефективний, ефективний API для зйомки повідомлень на всіх рівнях системи. Ця об'єднана система централізує зберігання даних журналу в пам'яті та сховищі даних на диску.

Apple настійно рекомендує використовувати для os_logподальшого ведення журналу всілякі повідомлення, включаючи інформацію, налагодження, повідомлення про помилки через його значно покращену продуктивність порівняно з попередніми системами ведення журналів, а також його централізований збір даних, що дозволяє зручно перевіряти журнал та активність для розробників. Насправді нова система, ймовірно, настільки низька, що не призведе до «ефекту спостерігача», де ваша помилка зникає, якщо ви вставите команду ведення журналу, перешкоджаючи часу виникнення помилки.

Ефективність відстеження активності, яка тепер є частиною нової системи Єдиного журналу

Детальніше про це можна детальніше дізнатися тут .

Підсумовуючи це: використовуйте print()для особистої налагодження для зручності (але повідомлення не буде реєструватися під час розгортання на пристроях користувача). Потім використовуйте Unified Logging ( os_log) якомога більше для всього іншого.


5

Існує ще один метод, dump()який можна також використовувати для ведення журналу:

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

Збирає вміст об'єкта за допомогою дзеркала до стандартного виводу.

З стандартних функцій бібліотеки Swift

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.