Rápido: imprimir() frente a println() frente a NSLog()

Resuelto User asked hace 10 años • 6 respuestas

¿Cuál es la diferencia entre printy NSLogcuándo printlndebo usar cada uno?

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

User avatar Sep 20 '14 23:09 User
Aceptado

Algunas diferencias:

  1. printfrente a println:

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

    Es printlnuna variación de esto que se eliminó en Swift 2 y ya no se usa. Si ve un código antiguo que utiliza println, ahora puede reemplazarlo de forma segura con print.

    En Swift 1.x, printno agregaba caracteres de nueva línea al final de la cadena impresa, mientras que printlnsí. 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:

    • NSLogagrega una marca de tiempo y un identificador a la salida, mientras que printno 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.

    • NSLogen iOS 10-13/macOS 10.12-10.x usa printfcadenas de formato estilo, por ejemplo

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

      que producirá:

      2017-06-09 11:57:55.642328-0700 MiAplicación[28937:1751492] 3.1416

    • NSLogdesde iOS 14/macOS 11 puede utilizar la interpolación de cadenas. (Por otra parte, en iOS 14 y macOS 11, generalmente preferiríamos Logger. NSLogConsulte el siguiente punto).

    Hoy en día, aunque NSLogtodavía funciona, generalmente usamos "registro unificado" (ver más abajo) en lugar de NSLog.

  3. A partir de iOS 14/macOS 11, tenemos Loggeruna interfaz para el sistema de "registro unificado". Para obtener una introducción Logger, consulte WWDC 2020 Explore el inicio de sesión en Swift .

    • Para utilizarlo Logger, debes importar os:

      import os
      
    • Al igual que NSLog, el registro unificado enviará mensajes tanto a la consola de depuración de Xcode como a la consola del dispositivo.

    • Crea un Loggery logun mensaje para él:

      let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
      logger.log("url = \(url)")
      

      Cuando observa la aplicación a través de la aplicación de consola externa, puede filtrar según subsystemy category. Es muy útil 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, ya sea .info, .debug, .error, .fault, .critical, .notice, .trace, etc.:

      logger.error("web service did not respond \(error.localizedDescription)")
      

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

    • De forma predeterminada, los datos no numéricos se ocultan en los registros. En el ejemplo en el que registró la URL, si la aplicación se invocó desde el propio dispositivo y la estaba mirando desde la aplicación de su consola macOS, verá lo siguiente en la consola macOS:

      URL = <privado>

      Si estás seguro de que este mensaje no incluirá datos confidenciales del usuario y deseas ver las cadenas en tu consola macOS, tendrías que hacer:

      logger.log("url = \(url, privacy: .public)")
      
    • Tenga en cuenta que en Xcode 15 y versiones posteriores, ahora puede filtrar el registro por tipo, subsistema, categoría o lo que sea. Personalmente, en proyectos grandes, encuentro útil usar un archivo fuente separado Loggerpara cada archivo fuente, luego puedo filtrar un registro voluminoso a algo más específico (por ejemplo, simplemente registrar mensajes de tipo "error" para una "categoría" particular, etc. ). Para obtener más información, consulte el vídeo de la WWDC 2023 Depuración con registro estructurado .

    • Además, a diferencia de printy NSLog, cuando usa LoggerXcode 15 o posterior, puede controlhacer clic (o righthacer clic, si ha habilitado el botón derecho del mouse) en un mensaje de registro en la consola de Xcode y elegir "Saltar a la fuente" para saltar. a la línea de código correspondiente.

  4. Antes de iOS 14/macOS 11, se introdujo iOS 10/macOS 10.12 os_logpara el “registro unificado”.

    • Importar os.log:

      import os.log
      
    • Debes definir el subsystemy category:

      let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
      
    • Al usar os_log, usaría un patrón de estilo printf en lugar de interpolación de cadenas:

      os_log("url = %@", log: log, url.absoluteString)
      
    • Puede especificar diferentes tipos de mensajes de registro, ya sea .info, .debug, .error, .fault(o .default):

      os_log("web service did not respond", type: .error)
      
    • No puedes usar la interpolación de cadenas cuando usas os_log. Por ejemplo con printy Loggerlo haces:

      logger.log("url = \(url)")
      

      Pero con os_log, tendrías que hacer:

      os_log("url = %@", url.absoluteString)
      
    • El os_logaplica la misma privacidad de datos, pero usted especifica la visibilidad pública en el formateador printf (por ejemplo, %{public}@en lugar de %@). Por ejemplo, si quisieras verlo desde un dispositivo externo, tendrías que hacer:

      os_log("url = %{public}@", url.absoluteString)
      
    • También puede utilizar el registro de "Puntos de interés" si desea ver rangos de actividades desde Instrumentos:

      let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)
      

      Y comience un rango con:

      os_signpost(.begin, log: pointsOfInterest, name: "Network request")
      

      Y terminar con:

      os_signpost(.end, log: pointsOfInterest, name: "Network request")
      

      Para obtener más información, consulte https://stackoverflow.com/a/39416673/1271826 .

    • Como Logger, OSLogpuede controlhacer clic (o righthacer clic) en el mensaje y saltar a la línea de código correspondiente en Xcode 15 y versiones posteriores.

En pocas palabras, printes suficiente para un registro simple con Xcode, pero el registro unificado (ya sea Loggero os_log) logra lo mismo pero ofrece capacidades mucho mayores.

El poder del registro unificado se pone de relieve al depurar aplicaciones de iOS que deben probarse fuera de Xcode. Por ejemplo, cuando se prueban procesos de aplicaciones iOS en segundo plano, como la recuperación en segundo plano, estar conectado al depurador de Xcode cambia el ciclo de vida de la aplicación . Por lo tanto, con frecuencia querrás realizar la prueba 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 declaraciones de registro de su dispositivo iOS desde la aplicación de consola macOS.

Rob avatar Sep 20 '2014 17:09 Rob

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

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

Actualizado a iOS 9

De forma predeterminada, la función finaliza la línea que imprime agregando un salto de línea.

print("Hello Swift")

terminador

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

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

Separador

Ahora puedes usar el separador para concatenar varios elementos.

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

Ambos

O podrías combinar el uso de esta manera.

print("Hello", "Swift", 2, separator:" ", terminator:".")
Jorge Casariego avatar Jun 16 '2015 18:06 Jorge Casariego

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

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

Ejemplos:

  • Instrumentos de cuerda
    • print("Hello World!")se convierteHello World
    • debugPrint("Hello World!")se convierte en "Hello World"(¡Comillas!)
  • Rangos
    • print(1..<6)se convierte1..<6
    • debugPrint(1..<6)se convierteRange(1..<6)

Cualquier clase puede personalizar su representación de cadena de depuración mediante CustomDebugStringConvertibleprotocolo.

Valentin Shergin avatar Dec 04 '2015 02:12 Valentin Shergin