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

450

¿Cuál es la diferencia entre print, NSLogy printlny cuándo debo utilizar cada uno?

Por ejemplo, en Python si quisiera imprimir un diccionario, lo haría print myDict, pero ahora tengo otras 2 opciones. ¿Cómo y cuándo debo usar cada uno?

Usuario
fuente
1
posible duplicado de la diferencia entre println e print en Swift
Connor
2
¿Qué pasa con NSLog e imprimir un NSDictionary no me da nada útil?
Usuario
Desde iOS 10.0 en adelante, se recomienda que se use os_log. Por favor vea mi respuesta a continuación .
HuaTham
Además de ver la documentación de Swift en os_log: intente ver la documentación completa de la página del objetivo-C. Es mucho más completo .
Miel

Respuestas:

758

Algunas diferencias

  1. printvs println:

    La printfunción imprime mensajes en la consola Xcode al depurar aplicaciones.

    Esta printlnes una variación de esto que se eliminó en Swift 2 y ya no se usa. Si ve un código antiguo que está usando println, ahora puede reemplazarlo con seguridad print.

    De vuelta en Swift 1.x, printno agregó caracteres de nueva línea al final de la cadena impresa, mientras que lo printlnhizo. Pero hoy en día, printsiempre agrega el carácter de nueva línea al final de la cadena, y si no desea que lo haga, proporcione un terminatorparámetro de "".

  2. NSLog:

    • NSLog es más lento

    • NSLogagrega una marca de tiempo e identificador a la salida, mientras printque no lo hará;

    • NSLoglas declaraciones aparecen tanto en la consola del dispositivo como en la consola del depurador, mientras que printsolo aparecen en la consola del depurador.

    • NSLogutiliza printfcadenas de formato de estilo, por ejemplo

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

      eso producirá:

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

  3. A partir de iOS 10 / macOS 10.12, existe una tercera alternativa, os_logparte del sistema de "registro unificado" (vea el video de WWDC 2016 Registro unificado y rastreo de actividad ).

    • Debe importar os.logantes de usar la os_logfunción:

      import os.log
    • Al igual que NSLog, también os_logenviará mensajes tanto a la consola de depuración de Xcode como a la consola del dispositivo

    • Ahora puede controlar los campos "subsistema" y "categoría" disponibles en la aplicación Consola. Por ejemplo:

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

      Cuando observa la aplicación a través de la aplicación de consola externa, no solo puede agregar estas columnas a la vista principal, sino que puede filtrar en función de ellas. Es muy útil cuando desea diferenciar sus mensajes de depuración de (a) los generados por otros subsistemas en nombre de su aplicación; o (b) mensajes de otras categorías o tipos.

    • Puede especificar diferentes tipos de mensajes de registro, o bien .info, .debug, .error, .fault(o .default):

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

      Por lo tanto, si usa la aplicación de consola externa, puede elegir ver solo los mensajes de ciertas categorías (por ejemplo, solo mostrar mensajes de depuración si elige "Incluir mensajes de depuración" en el menú "Acción" de la consola). Esta configuración también dicta muchos detalles sutiles sobre si las cosas se registran en el disco o no. Vea el video de WWDC para más detalles.

    • No se puede usar la interpolación de cadenas cuando se usa os_log. Por ejemplo, no puedes hacer:

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

      Tendrías que hacer:

      os_log("url = %@", url.absoluteString)
    • Una de las razones de la limitación anterior es apoyar la privacidad de los datos. Los tipos de datos primitivos (por ejemplo, números) son públicos de forma predeterminada y los objetos (por ejemplo, cadenas) son privados de forma predeterminada. En el ejemplo anterior en el que registraste la URL, si la aplicación se invocara desde el dispositivo mismo y estuvieras viendo desde la aplicación de consola de tu Mac, verías:

      url = <privado>

      Si quisieras verlo desde un dispositivo externo, deberías hacer lo siguiente:

      os_log("url = %{public}@", url.absoluteString)
    • Tenga en cuenta que NSLogahora usa el sistema de notificación unificado detrás de escena, pero con las siguientes advertencias:

      • No puede controlar el subsistema o categoría o tipo de registro;

      • No es compatible con la configuración de privacidad.

En pocas palabras, printes suficiente para tareas simples, pero NSLoges útil porque incluye información de marca de tiempo para usted.

El poder de se os_logpone de relieve cuando se depuran las aplicaciones de iOS que deben probarse fuera de Xcode. Por ejemplo, cuando se prueban procesos de aplicaciones iOS en segundo plano, como la búsqueda en segundo plano, estar conectado al depurador Xcode cambia el ciclo de vida de la aplicación . Por lo tanto, con frecuencia querrá probar en un dispositivo físico, ejecutando la aplicación desde el propio dispositivo, no iniciando la aplicación desde el depurador de Xcode. El registro unificado le permite seguir viendo las os_logdeclaraciones de su dispositivo iOS desde la aplicación de consola macOS.

Robar
fuente
37
Bonito resumen! Para agregar algunos más: puede pasar un NSString a println, pero no NSLog; puede agregar argumentos para NSLog, pero no println; La interpolación de cadenas de estilo rápido a veces falla para NSLog, pero no println.
Bao Lei
2
Una nota interesante sobre la optimización del compilador Swift y el uso de print () medium.com/ios-os-x-development/…
Carl
@Rob si uso print, ¿aparece en la consola del depurador o no? ¿O deberíamos usar debugPrint?
1
Si lo usa print, aparece en el área de depuración de Xcode, al igual que debugPrint. La única diferencia es que printtermina llamando al descriptionmétodo del objeto y a las debugPrintllamadas debugDescription, que pueden ser más detalladas que description.
Rob
@Honey, este hilo de comentarios se marcó como excesivamente largo, por lo que solo quería recordarte que los comentarios no son para debates prolongados o sesiones de depuración. Si usted tiene algo que se puede pedir como una cuestión que es adecuado para el formato de desbordamiento de pila, a continuación, por favor pregunte como una pregunta para que todos puedan beneficiarse de sus respuestas. Si no funciona como una pregunta, entonces necesitará tomar la discusión para chatear. Reserve comentarios solo para pedir aclaraciones o hacer observaciones rápidas.
Cody Gray
80

Si está usando Swift 2 , ahora solo puede usar print () para escribir algo en la salida.

Apple ha combinado las funciones println () e print () en una.

Actualizado a iOS 9

Por defecto, la función termina la línea que imprime agregando un salto de línea.

print("Hello Swift")

Terminator

Para imprimir un valor sin un salto de línea después de él, pase una cadena vacía como terminador

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

Separador

Ahora puede usar el separador para concatenar múltiples elementos

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

Ambos

O podrías combinarlo de esta manera

print("Hello", "Swift", 2, separator:" ", terminator:".")
Jorge Casariego
fuente
55
appendNewlinetiene un valor predeterminado detrue
Adam
1
En iOS (9.0) necesita usar terminator : "", por ejemploprint("...", terminator: "")
Khotu Nam
La declaración en su primera oración es incorrecta. NSLog () todavía funciona, incluso en la última versión de Swift 2.x
Sebastian
62

¡Además, Swift 2 tiene debugPrint()(y CustomDebugStringConvertibleprotocolo)!

No se olvide de debugPrint()cuál funciona print()pero es más adecuado para la depuración .

Ejemplos:

  • Instrumentos de cuerda
    • print("Hello World!") se convierte Hello World
    • debugPrint("Hello World!")se convierte "Hello World"(¡Citas!)
  • Rangos
    • print(1..<6) se convierte 1..<6
    • debugPrint(1..<6) se convierte Range(1..<6)

Cualquier clase puede personalizar su representación de cadena de depuración a través del CustomDebugStringConvertibleprotocolo.

Valentin Shergin
fuente
2
DebugPrintableSe ha cambiado el nombre del CustomDebugStringConvertibleprotocolo a protocolo .
Franklin Yu
¡Gracias Franklin!
Valentin Shergin
Así de Swift descriptiones debugDescriptioncomo Python stres repr?
BallpointBen
Sí, eso creo.
Valentin Shergin
39

Para agregar a la respuesta de Rob, desde iOS 10.0, Apple ha introducido un sistema completamente nuevo de "Registro unificado" que reemplaza a los sistemas de registro existentes (incluidos ASL y Syslog, NSLog), y también supera los enfoques de registro existentes en rendimiento, gracias a sus nuevas técnicas que incluyen registro de compresión de datos y recopilación de datos diferidos.

De Apple :

El sistema de registro unificado proporciona una API única, eficiente y eficiente para capturar mensajes en todos los niveles del sistema. Este sistema unificado centraliza el almacenamiento de datos de registro en la memoria y en un almacén de datos en el disco.

Apple recomienda encarecidamente utilizar os_logen adelante para registrar todo tipo de mensajes, incluidos mensajes de información, depuración y error, debido a su rendimiento mucho mejor en comparación con los sistemas de registro anteriores, y su recopilación de datos centralizada que permite la inspección conveniente de registros y actividades para los desarrolladores. De hecho, es probable que el nuevo sistema tenga una huella tan baja que no causará el "efecto de observador" donde su error desaparece si inserta un comando de registro, lo que interfiere con el tiempo del error.

Rendimiento del seguimiento de actividad, ahora parte del nuevo sistema de registro unificado

Puede obtener más información sobre esto en detalles aquí .

Para resumir: utilícelo print()para su depuración personal por conveniencia (pero el mensaje no se registrará cuando se implemente en los dispositivos de los usuarios). Luego, use el registro unificado ( os_log) tanto como sea posible para todo lo demás.

HuaTham
fuente
5

Hay otro método llamado dump()que también se puede usar para iniciar sesión:

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

Vuelca el contenido de un objeto usando su espejo a la salida estándar.

De las funciones de la biblioteca estándar de Swift

JAL
fuente