Swift: печать () против печати () против NSLog ()

286

В чем разница между print, NSLog и println и когда я должен использовать каждый?

Например, в Python, если бы я хотел напечатать словарь, я бы просто print myDict, но теперь у меня есть еще 2 варианта. Как и когда я должен использовать каждый?

  • 1
    возможный дубликат разницы между println и print в Swift
  • 2
    как насчет NSLog и печати NSDictionary не дает мне ничего полезного?
Показать ещё 2 комментария
Теги:
logging
console
debugging

5 ответов

456
Лучший ответ

Несколько отличий:

  • print vs println:

    Функция print печатает сообщения в консоли Xcode при отладке приложений.

    println - это вариация, которая была удалена в Swift 2 и больше не используется. Если вы видите старый код, который использует println, теперь вы можете спокойно заменить его на print.

    Назад в Swift 1.x, print не добавлял символы новой строки в конце напечатанной строки, тогда как println. Но в настоящее время print всегда добавляет символ новой строки в конце строки, и если вы этого не хотите, поставьте параметр terminator "".

  • 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

  • Эффективный 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)
      

      Когда вы наблюдаете приложение через внешнее консольное приложение, вы можете не только добавлять эти столбцы к основному виду, но и фильтровать на основе этого. Это очень полезно, когда вы хотите отличить отладочные сообщения от (а) тех, которые генерируются другими подсистемами от имени вашего приложения; или (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 Console, вы увидите:

      url = <private>

      Если вы хотите увидеть его с внешнего устройства, вам нужно будет:

      os_log("url = %{public}@", url.absoluteString)
      
    • Примечание. NSLog теперь использует единую систему уведомлений за кулисами, но со следующими оговорками:

      • Вы не можете управлять подсистемой или типом категории или журнала;

      • Он не поддерживает настройки конфиденциальности.

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

Сила os_log приходит в полное облегчение при отладке приложений iOS, которые необходимо протестировать вне Xcode. Например, при тестировании фоновых процессов приложения iOS, таких как фоновое извлечение, подключение к отладчику Xcode изменяет жизненный цикл приложения. Таким образом, вы часто захотите протестировать на физическом устройстве, запуская приложение с самого устройства, не запуская приложение из отладчика Xcodes. Унифицированное ведение журнала позволяет вам просматривать инструкции iOS устройства os_log из приложения MacOS Console.

  • 32
    Хорошее резюме! Чтобы добавить еще несколько: вы можете передать NSString в println, но не NSLog; Вы можете добавить аргументы для NSLog, но не println; Интерполяция строк в стиле Swift иногда дает сбой для NSLog, но не для println.
  • 2
    интересная заметка об оптимизации компилятора Swift и использовании print () medium.com/ios-os-x-development/…
Показать ещё 5 комментариев
70

Если вы используете Swift 2, теперь вы можете использовать print() только для записи чего-либо на выходе.

Apple объединила функции println() и print() в один.

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

По умолчанию функция завершает печать строки путем добавления разрыва строки.

print("Hello Swift")

Terminator

Чтобы напечатать значение без разрыва строки после него, передать пустую строку в качестве терминатора

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

Разделитель

Теперь вы можете использовать разделитель для объединения нескольких элементов

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

И

Или вы можете комбинировать использование таким образом

print("Hello", "Swift", 2, separator:" ", terminator:".")
  • 5
    appendNewline имеет значение по умолчанию true
  • 0
    Спасибо @ Адам, я отредактировал свой ответ
Показать ещё 3 комментария
57

Кроме того, 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 .
  • 0
    Спасибо, Франклин!
Показать ещё 2 комментария
13

Чтобы добавить к Rob ответ, начиная с iOS 10.0, Apple представила совершенно новую систему унифицированного ведения журнала, которая заменяет существующие системы ведения журнала (включая ASL и Syslog, NSLog), а также превосходит существующие подходы к регистрации в производительности, благодаря новые методы, включая сжатие данных журнала и отложенный сбор данных.

От Apple:

Единая система протоколирования предоставляет единый эффективный API-интерфейс для захвата сообщений на всех уровнях системы. Эта унифицированная система централизует хранение данных журнала в памяти и в хранилище данных на диске.

Apple настоятельно рекомендует использовать os_log для записи всех видов сообщений, включая информацию, отладочную информацию, сообщения об ошибках из-за ее повышенной производительности по сравнению с предыдущими системами ведения журнала и централизованный сбор данных, позволяющий вести журнал регистрации и активности Разработчики. На самом деле, новая система, вероятно, настолько мала, что не приведет к "эффекту наблюдателя", когда ваша ошибка исчезнет, ​​если вы введете команду регистрации, что мешает синхронизации ошибки.

Изображение 1680

Подробнее об этом можно узнать здесь.

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

2

Существует еще один метод под названием dump(), который также можно использовать для ведения журнала:

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

Сбрасывает содержимое объектов, используя его зеркало, на стандартный вывод.

От Функции стандартной библиотеки Swift

Ещё вопросы

Сообщество Overcoder
Наверх
Меню