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


450

Qual è la differenza tra print, NSLoge printlne quando devo usare ciascuno?

Ad esempio, in Python se volessi stampare un dizionario, lo farei print myDict, ma ora ho altre 2 opzioni. Come e quando dovrei usarli?


1
possibile duplicato della differenza tra println e print in Swift
Connor

2
che dire di NSLog e stampare un NSDictionary non mi dà nulla di utile?
Utente

Da iOS 10.0 in avanti si consiglia di utilizzarlo os_log. Si prega di vedere la mia risposta qui sotto .
HuaTham,

Oltre a vedere la documentazione di Swift su os_log: prova a vedere la documentazione completa della pagina obiettivo-C. È molto più completo .
Miele,

Risposte:


758

Alcune differenze:

  1. printvs println:

    La printfunzione stampa i messaggi nella console Xcode durante il debug delle app.

    Questa printlnè una variante che è stata rimossa in Swift 2 e non viene più utilizzata. Se vedi il vecchio codice che sta utilizzando println, ora puoi tranquillamente sostituirlo con print.

    Indietro in Swift 1.x, printnon ha aggiunto caratteri di nuova riga alla fine della stringa stampata, printlninvece. Ma al giorno d'oggi, printaggiunge sempre il carattere di nuova riga alla fine della stringa e, se non lo si desidera, fornire un terminatorparametro di "".

  2. NSLog:

    • NSLog è più lento;

    • NSLogaggiunge un timestamp e un identificatore all'output, mentre printnon lo farà;

    • NSLogle istruzioni compaiono sia nella console del dispositivo che nella console del debugger, mentre printappaiono solo nella console del debugger.

    • NSLogutilizza printfstringhe di formato stile, ad es

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

      che produrrà:

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

  3. A partire da iOS 10 / macOS 10.12, esiste una terza alternativa, os_logparte del sistema di "unified logging" (vedi video Unified Logging e Activity WWDC 2016 ).

    • È necessario importare os.logprima di utilizzare la os_logfunzione:

      import os.log
    • Ad esempio NSLog, os_loginvierà messaggi sia alla console di debug di Xcode sia alla console del dispositivo

    • Ora puoi controllare i campi "sottosistema" e "categoria" disponibili nell'app Console. Per esempio:

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

      Quando osservi l'app tramite l'app Console esterna, non solo puoi aggiungere queste colonne alla vista principale, ma puoi filtrarle in base a queste. È molto utile quando si desidera differenziare i messaggi di debug da (a) quelli generati da altri sottosistemi per conto della propria app; o (b) messaggi di altre categorie o tipi.

    • È possibile specificare diversi tipi di messaggi di registro, o .info, .debug, .error, .fault(o .default):

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

      Pertanto, se si utilizza l'app console esterna, è possibile scegliere di visualizzare solo i messaggi di determinate categorie (ad es. Mostrare i messaggi di debug solo se si seleziona "Includi messaggi di debug" nel menu "Azione" della console). Queste impostazioni dettano anche molti dettagli di problemi sottili sul fatto che le cose siano registrate o meno sul disco. Guarda il video del WWDC per maggiori dettagli.

    • Non è possibile utilizzare l'interpolazione di stringhe durante l'utilizzo os_log. Ad esempio non puoi fare:

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

      Dovresti fare:

      os_log("url = %@", url.absoluteString)
    • Uno dei motivi della limitazione di cui sopra è supportare la privacy dei dati. I tipi di dati primitivi (ad esempio numeri) sono pubblici per impostazione predefinita e gli oggetti (ad esempio stringhe) sono privati ​​per impostazione predefinita. Nell'esempio precedente in cui hai registrato l'URL, se l'app fosse invocata dal dispositivo stesso e guardassi dall'app Console del tuo Mac, vedresti:

      url = <privato>

      Se volessi vederlo da un dispositivo esterno, dovresti fare:

      os_log("url = %{public}@", url.absoluteString)
    • Nota, NSLogora utilizza il sistema di notifica unificato dietro le quinte, ma con le seguenti avvertenze:

      • Non è possibile controllare il sottosistema o la categoria o il tipo di registro;

      • Non supporta le impostazioni sulla privacy.

In conclusione, printè sufficiente per attività semplici, ma NSLogè utile perché include informazioni di data e ora per te.

La potenza di os_logviene in netto rilievo durante il debug di app iOS che devono essere testate al di fuori di Xcode. Ad esempio, durante il test di processi dell'app in background iOS come il recupero in background, la connessione al debugger Xcode modifica il ciclo di vita dell'app . Quindi, spesso vorrai testare su un dispositivo fisico, eseguendo l'app dal dispositivo stesso, non avviando l'app dal debugger di Xcode. La registrazione unificata ti consente di guardare le os_logdichiarazioni del tuo dispositivo iOS dall'app macOS Console.


37
Bel riassunto! Per aggiungerne altri: puoi passare un NSString a println, ma non NSLog; puoi aggiungere args per NSLog, ma non println; L'interpolazione di stringhe in stile rapido a volte si arresta in modo anomalo per NSLog, ma non println.
Bao Lei il

2
una nota interessante sull'ottimizzazione del compilatore Swift e sull'uso di print () medium.com/ios-os-x-development/…
Carl

@Rob se uso print, allora appare nella console del debugger o no? O dovremmo usare debugPrint?

1
Se lo usi print, viene visualizzato nell'area di debug di Xcode, proprio come debugPrint. L'unica differenza è che printfinisce per chiamare il descriptionmetodo dell'oggetto e le debugPrintchiamate debugDescription, che possono essere più dettagliate di description.
Rob

@Ciao, questo thread di commenti è stato segnalato come eccessivamente lungo, quindi volevo solo ricordarti che i commenti non sono per discussioni estese o sessioni di debug. Se hai una domanda che può essere posta come una domanda adatta al formato Stack Overflow, ti preghiamo di farla come domanda in modo che tutti possano trarre vantaggio dalle sue risposte. Se non funziona come una domanda, dovrai fare una discussione per chattare. Prenota commenti solo per chiedere chiarimenti o fare osservazioni rapide.
Cody Grey

80

Se stai usando Swift 2 , ora puoi usare solo print () per scrivere qualcosa nell'output.

Apple ha combinato entrambe le funzioni println () e print () in una.

Aggiornato a iOS 9

Per impostazione predefinita, la funzione termina la riga stampata aggiungendo un'interruzione di riga.

print("Hello Swift")

Terminator

Per stampare un valore senza un'interruzione di riga dopo di esso, passare una stringa vuota come terminatore

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

Separatore

Ora puoi utilizzare il separatore per concatenare più elementi

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

Tutti e due

Oppure potresti combinare usando in questo modo

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

5
appendNewlineha un valore predefinito ditrue
Adam

1
In iOS (9.0) devi usare terminator : "", ad esempioprint("...", terminator: "")
Khotu Nam

L'affermazione nella tua prima frase non è corretta. NSLog () funziona ancora, anche nell'ultimo Swift 2.x
Sebastian,

62

Inoltre, Swift 2 ha debugPrint()(e CustomDebugStringConvertibleprotocollo)!

Non dimenticare debugPrint()quale funziona print()ma più adatto per il debug .

Esempi:

  • stringhe
    • print("Hello World!") diventa Hello World
    • debugPrint("Hello World!")diventa "Hello World"(Citazioni!)
  • Intervalli
    • print(1..<6) diventa 1..<6
    • debugPrint(1..<6) diventa Range(1..<6)

Qualsiasi classe può personalizzare la rappresentazione della stringa di debug tramite CustomDebugStringConvertibleprotocollo.


2
DebugPrintableprotocollo è stato rinominato CustomDebugStringConvertibleprotocollo .
Franklin Yu,

Grazie Franklin!
Valentin Shergin,

Quindi di Swift descriptionè quello di debugDescriptioncome Python strè quello repr?
BallpointBen,

Penso di sì.
Valentin Shergin,

39

Per aggiungere la risposta di Rob, da iOS 10.0, Apple ha introdotto un sistema "Unified Logging" completamente nuovo che sostituisce i sistemi di registrazione esistenti (inclusi ASL e Syslog, NSLog) e supera anche gli approcci di registrazione esistenti nelle prestazioni, grazie alle sue nuove tecniche tra cui registrazione dei dati di compressione e raccolta dei dati differiti.

Da Apple :

Il sistema di registrazione unificato fornisce un'API unica, efficiente e performante per l'acquisizione di messaggi a tutti i livelli del sistema. Questo sistema unificato centralizza la memorizzazione dei dati di registro in memoria e in un archivio dati su disco.

Apple consiglia vivamente di utilizzare il os_logfuturo per registrare tutti i tipi di messaggi, inclusi informazioni, debug, messaggi di errore a causa delle sue prestazioni molto migliorate rispetto ai sistemi di registrazione precedenti e la sua raccolta centralizzata di dati che consente un comodo controllo di registro e attività per gli sviluppatori. In effetti, il nuovo sistema è probabilmente così ridotto che non causerà l'effetto "osservatore" in cui il bug scompare se si inserisce un comando di registrazione, interferendo con la tempistica del bug.

Performance of Activity Tracing, ora parte del nuovo sistema di Unified Logging

Puoi saperne di più su questo nei dettagli qui .

Per riassumere: utilizzare print()per il debug personale per comodità (ma il messaggio non verrà registrato quando distribuito sui dispositivi degli utenti). Quindi, utilizza Unified Logging ( os_log) il più possibile per tutto il resto.


5

Esiste un altro metodo chiamato dump()che può essere utilizzato anche per la registrazione:

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

Esegue il dump del contenuto di un oggetto usando il suo mirror nell'output standard.

Da Swift Standard Library Functions

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.